• Codeforces Round #228 (Div. 1)


    今天学长给我们挂了一套Div.1的题,难受,好难啊。

    Problem A:

    题目大意:给你n个数字,让你叠成n堆,每个数字上面的数的个数不能超过这个数,如 3 上面最多放三个数字

    问你,最少能放几堆。

    刚开始看错题意,以为只要比这个数字小的数都能放上去,后来看清了题意,一直想的是怎么从下往上放,感觉

    二分加贪心可以做,但是太麻烦了,后来想如果从上往下放就好做多了,每次从小的开取,这样到取下一个数的

    时候就知道上面有多少,能不能取这个数,这样的话也能保证这一堆是最优的。

    #include<bits/stdc++.h>
    using namespace std;
    int a[105],n;
    bool vis[105];
    int main()
    {
        scanf("%d",&n);
        for(int i=0;i<n;i++) scanf("%d",&a[i]);
        sort(a,a+n);
        int sum=n;
        int ans=0;
        int now=0;
        while(sum)
        {
            //cout<<sum<<endl;
            for(int i=0;i<n;i++)
            {
                if(!vis[i])
                {
                    if(a[i]>=now)
                    {
                        now++;
                        vis[i]=1;
                        sum--;
                    }
                }
            }
            ans++;
            now=0;
        }
        cout<<ans<<endl;
        return 0;
    }
    View Code

    Problem B:

    题目大意:让你给出一幅图,让这幅图从1节点到2节点的最短路的条数为k,且节点个数不能超过1000个。

    思路:如果没有节点个数的限制那么这题就非常好些,但有了限制的话其实我们可以这么想,我们可以把

    k用2进制表示,这样就能将条数表示成2*2*2...+2*2...的方式。刚写的时候每条单链都是新的,取极限值的

    时候会超过1000个节点,于是我就先预处理处一条长度为100的单链重复利用。

    #include<bits/stdc++.h>
    using namespace std;
    int k;
    int a[100],pos;
    bool vis[1500][1500];
    int len[205];//len[i]表示还需要增加i长度的链需要接在那个节点上
    int main()
    {
        vis[2][999]=vis[999][2]=1;
        len[2]=999;
        len[1]=2;
        int ct=2;
        for(int i=999;i>=900;i--)
        {
            vis[i][i-1]=vis[i-1][i]=1;
            len[++ct]=i-1;
        }
        cin>>k;
        pos=0;
        while(k)
        {
            a[pos++]=k&1;
            k=k>>1;
        }
        pos--;
        int cnt=2;
        for(int i=pos;i>=0;i--)
        {
            if(a[i])
            {
                for(int j=1;j<=i;j++)
                {
                    if(j==1)
                    {
                        cnt++;
                        vis[cnt][1]=1;
                        vis[1][cnt]=1;
                        cnt++;
                        vis[cnt][1]=1;
                        vis[1][cnt]=1;
                    }
                    else
                    {
                        cnt++;
                        vis[cnt][cnt-1]=vis[cnt-1][cnt]=1;
                        vis[cnt][cnt-2]=vis[cnt-2][cnt]=1;
                        cnt++;
                        vis[cnt][cnt-2]=vis[cnt-2][cnt]=1;
                        vis[cnt][cnt-3]=vis[cnt-3][cnt]=1;
                    }
                }
                if(i==pos)
                {
                    vis[cnt][2]=vis[2][cnt]=1;
                    vis[cnt-1][2]=vis[2][cnt-1]=1;
                }
                else
                {
                    if(!i) vis[1][len[pos+1]]=vis[len[pos+1]][1]=1;
                    else
                    {
                        vis[cnt][len[pos-i+1]]=vis[len[pos-i+1]][cnt]=1;
                        vis[cnt-1][len[pos-i+1]]=vis[len[pos-i+1]][cnt-1]=1;
                    }
                }
            }
        }
        cout<<"999"<<endl;
        for(int i=1;i<=999;i++)
        {
            for(int j=1;j<=999;j++)
            {
                if(vis[i][j] && i!=j) printf("Y");
                else printf("N");
            }
            puts("");
        }
        return 0;
    }
    View Code

    Problem C:

    题目大意:有n堆牌,A只能从顶部取牌,B只能从底部取牌,A先取,如果每个人都希望自己的点数总和

    最大,且每个人的操作都最优,问你最后两个人的点数分别是什么。

    思路:这个题还是比较简单的贪心,我们可以这么想,我们把每堆牌都分成上堆和下堆,如果是奇数则

    把中间的牌取出来放到一个数组里。如果对A来说下堆有对他有利的大牌,他会想去拿,但是B也是最优

    操作,B不会让A拿到,对B来说也是同理,所以最后肯定上堆都是A的下堆都是B的,奇数堆取出来的一

    个一个分。

    #include<bits/stdc++.h>
    using namespace std;
    vector<int> zhong;
    bool cmp(int a,int b)
    {
        return a>b;
    }
    int main()
    {
        int n;
        cin>>n;
        int sum1=0,sum2=0;
        for(int i=1;i<=n;i++)
        {
            int m;
            scanf("%d",&m);
            if(m%2==0)
            {
                for(int i=1;i<=m;i++)
                {
                    int g;scanf("%d",&g);
                    if(i<=m/2) sum1+=g;
                    else sum2+=g;
                }
            }
            else
            {
                for(int i=1;i<=m;i++)
                {
                    int g;scanf("%d",&g);
                    if(i<=m/2) sum1+=g;
                    else if(i==m/2+1) zhong.push_back(g);
                    else sum2+=g;
                }
            }
        }
        sort(zhong.begin(),zhong.end(),cmp);
        for(int i=0;i<zhong.size();i++)
        {
            if(i%2==0) sum1+=zhong[i];
            else sum2+=zhong[i];
        }
        printf("%d %d
    ",sum1,sum2);
        return 0;
    }
    View Code
  • 相关阅读:
    unittest_assert断言(4)
    unittest_skip跳过用例执行(3)
    unittest_TestSuite测试套件(2)
    unittest_认识unittest(1)
    Selenium_POM架构(17)
    【转】HTML基本代码
    cursor 鼠标样式的几种样式
    【笔记】在json-lib中如何不序列化某些字段
    关于Ext的一些使用心得
    GIT
  • 原文地址:https://www.cnblogs.com/CJLHY/p/7229417.html
Copyright © 2020-2023  润新知