zoukankan      html  css  js  c++  java
  • 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
  • 相关阅读:
    记录锁
    linux多线程同步pthread_cond_XXX条件变量的理解
    设置创建文件掩码遇到的问题
    函数的可重入和线程安全
    sigemptyset,sigfillset,sigaddset,sigdelset,sigismember,sigprocmask,sigpendmask作用
    嵌入式中断服务函数的一些特点
    linux alarm函数解除read write等函数的阻塞
    孤儿进程,僵死进程
    标准IO的缓冲问题
    《实用技巧》——让你的网站变成响应式的3个简单步骤
  • 原文地址:https://www.cnblogs.com/Tianwell/p/11475706.html
Copyright © 2011-2022 走看看