Educational Codeforces Round 72 (Div. 2)

本菜鸡只写了前 四题...

A题:Creating a Character

原题链接

题意:

给两个个属性,力量,智力,以及你有的分配点数。给出基础力量智力数值,以及拥有的剩余分配点数值。你需要将点数分配完,并且保证力量的 值大于智力,输出能够分配的可能数。不能就输出0.

思路:

我列了一个方程:设 力量为a,智力为b,分配点数值为c. 设分到力量的为 X,分到 智力为 Y. 则 a + X = b + Y , X + Y  =  c ; 其中 Y 为 b能够分配的最大值,求解 Y 即可. 由于有奇偶问题,所以我就取

max(c-X,Y) 作为Y的解

code:

#include <iostream>
#include <algorithm>
#include <cmath>
#include <cstring>
#include <string>
using namespace std;
int main(){
    int T;
    cin>>T;
    while(T--){
        int a,b,c;
        cin>>a>>b>>c;
        int x,y;
        x = (c-a+b)/2;
        y = (a-b+c)/2;
        int ans = max(c-x,y);
        if(b+c<a) cout<<c+1<<endl;
        else if(a+c<=b) cout<<0<<endl; 
        else cout<<ans<<endl;
    }
} 
View Code

 

B题:Zmei Gorynich

题意:

给 N 个技能组,每个技能组 会造成 a 点伤害, 如果对手在收到 a点伤害后剩余的血量 大于0 则会 在该回合 回复 b点。 可以选择任意技能组,重复任意次。输出能打败对手的最少回合数.

思路:

由于在某回合造成伤害后 对手会 回血,所以我们选取其中 造成伤害最大的作为最后一击。其他使用技能所造成的伤害即是 (a-b),我们再选取 (a-b)最大的技能去计算剩下还需打多少次即可。

code:

#include <algorithm>
#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <cmath>
#define IOS ios::sync_with_stdio(0); cin.tie(0);
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> pii;
const double Pi = acos(-1.0);
const double esp = 1e-9;
const int inf = 0x3f3f3f3f;
const int maxn = 1e5+7;
const int maxm = 1e6+7;
const int mod = 1e9+7;

 
int main(){
    IOS
    int T;
    cin >> T;
    while (T--){
        int n, m;
        cin >> n >> m;
        bool can = true;
        int cnt = 0;
        int maxx = 0;//最大的
        int maxsub = 0;//最大减少生命值
        for(int i=1;i<=n;i++){
            int x, y;
            scanf("%d%d", &x, &y);
 
            maxx = max(maxx, x);//取最大威力
            maxsub = max(maxsub, x - y);//最大减少生命值
             //无法处理
            if (x < m && x - y <= 0){
                cnt++;
                if (cnt == n)//都无法处理,false
                    can = false;
            }
         }
        if (can){
            if (maxx >= m)//可以一拳打死
                cout << 1 << endl;
            else{
                int rest = m - maxx;
                if (rest % maxsub == 0)//如果整数次刚好剩下最大威力
                    cout << rest / maxsub + 1 << endl;
                else cout << rest / maxsub + 2 << endl;//否则再攻击一次使生命值小于最大威力
            }
        }
        else cout << -1 << endl;//不可以
    }
}
View Code

 

C. The Number Of Good Substrings

题意:

给一个01串,选择一个区间 (l,r) 如果 区间长度 r - l +1 == (该区间01串形成的二进制数转换成十进制的数值),统计符合这样区间的个数

思路:

我们观察一下就会发现,要满足条件,即所选区间长度肯定大于等于从第一个 1 开始往后形成的二进制数值。(比如像 111 (8) 要形成这样即需要在 111 前面补上 5个前缀0)

所以我们对01串遍历时统计每一个连续的前导0个数,然后暴力枚举(延长01串),如果 满足所选区间长度大于等于所形成的二进制数 即符合条件。

code:

#include <algorithm>
#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <cmath>
#include <vector>
#define IOS ios::sync_with_stdio(0); cin.tie(0);
#define mp make_pair
#define Accept 0
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> pii;
const double Pi = acos(-1.0);
const double esp = 1e-9;
const int inf = 0x3f3f3f3f;
const int maxn = 1e5+7;
const int maxm = 1e6+7;
const int mod = 1e9+7;
 
int a[maxm];
string s;
int main(){
    IOS
    int T;
    cin>>T;
    while(T--){
        int ans = 0;
        cin>>s;
        int len = s.length();
        for(int i=0;i<len;i++){
            if(s[i]=='0') a[i] =0; 
            else a[i] = 1;
        }
        int cnt = 0;//前导零长度
        for(int i=0;i<len;i++){
            if(!a[i]) {cnt++; continue;}
            else{
                int tmp = 0;
                for(int j=0;j+i<len&&j<30;j++){
                    tmp = (tmp<<1)|a[i+j];//取后面位数
                    if(cnt+j+1>=tmp) ans++; 
                }
                cnt = 0;
            }
 
        }
        cout<<ans<<endl;
    }
}
View Code

 

D.Coloring Edges

题意:给出一张有向图,你需要对图上的边进行上色。不能对环全部染成同样的颜色,求最后最多需要多少种颜色,以及输出每条边的染色情况

思路:对于有向环判环我们用 拓扑排序处理下,把所有的环部分处理出来,如果没有环,则全为1,否则对环内部最后一条边输出2,用一个增序判断即可)

#include <algorithm>
#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <cmath>
#include <vector>
#include <stack>
#include <queue>
#define IOS ios::sync_with_stdio(0); cin.tie(0);
#define mp make_pair
#define Accept 0
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> pii;
const double Pi = acos(-1.0);
const double esp = 1e-9;
const int inf = 0x3f3f3f3f;
const int maxn = 5e3+7;
const int maxm = 5e3+7;
const int mod = 1e9+7;

struct Edge
{
    int u,v;
    int next;
}edge[maxm];
bool flag;
int ans;
int in[maxn];
int head[maxn];
int vis[maxn];
int top;
queue<int>Q;

void init(){
    memset(head,-1,sizeof(head));
    memset(in,0,sizeof(in));
    top  = 0;
    flag = true;
}
void add(int u,int v){
    edge[top].v = v;
    edge[top].next = head[u];
    edge[top].u = u;
    head[u] = top++;
}
void topo(int n,int m){
    for(int i=1;i<=n;i++) 
        if(!in[i]) Q.push(i);
    while(!Q.empty()){
        int u = Q.front();
        Q.pop();
        for(int i = head[u]; ~i ;i= edge[i].next){
            int v = edge[i].v;
            in[v]--;
            if(!in[v]) Q.push(v);
        }
    }
    for(int i=1;i<=n;i++){
        if(in[i]!=0) flag = false;
    }
    if(flag) {
        cout<<1<<endl;
        for(int i=0;i<m;i++)
            cout<<1<<" ";
    }else{
        cout<<2<<endl;
        for(int i=0;i<m;i++){
            if(edge[i].u<edge[i].v) cout<<1<<" ";
            else cout<<2<<" ";
        }
    } 
}
int main(){
    IOS
    int n,m;
    cin>>n>>m;
    init();
    int u,v;
    for(int i=0;i<m;i++){
        cin>>u>>v;
        add(u,v);
        in[v]++;
    }
    topo(n,m);
    return 0;
}
View Code

 

posted @ 2019-09-06 16:45  Tianwell  阅读(210)  评论(0编辑  收藏  举报