zoukankan      html  css  js  c++  java
  • Codeforces Round #661 (Div. 3)(A->D)

    A:http://codeforces.com/contest/1399/problem/A

    解析:

    不多说了,直接sort,判是否存在相邻差>1

    #include<iostream>
    #include<cstring>
    #include<algorithm>
    #include<stack>
    using namespace std;
    typedef long long ll;
    const int maxn=60;
    int l[maxn],r[maxn];
    char ch[3*maxn];
    int a[maxn];
    int pos[maxn];
    int main()
    {
        int t;
        cin>>t;
        while(t--)
        {
            int n;
            cin>>n;
            for(int i=1;i<=n;i++)
                cin>>a[i];
            if(n==1)
            {
                cout<<"YES"<<endl;continue;
            }
            sort(a+1,a+1+n);
            int ok=0;
            for(int i=2;i<=n;i++)
                if(abs(a[i]-a[i-1])>1)
                {
                    ok=1;break;
                }
            if(ok)
                cout<<"NO"<<endl;
            else
                cout<<"YES"<<endl;
        }
    }

    B:http://codeforces.com/contest/1399/problem/B

    题意:

    长度为n的a[]和b[]

    三种操作:

    1. ai--

    2. bi--

    3. ai和bi同时减1

    分别把a[]和b[]变成全相等数组,问最少需要的操作数。a[]不一定要和b[]相等。

    解析:

    因为只存在自减操作,所以元素并不会增大。所以最少需要的操作,一定是a[]和b[]变成对应的最小值。

    所以先找到各自的最小值。

    遍历a[]和b[],对于每一个ai,bi,算出俩差值,先同时减,然后较大的再自减就可以了。

    #include<iostream>
    #include<cstring>
    #include<algorithm>
    #include<stack>
    #include<map>
    using namespace std;
    typedef long long ll;
    const int maxn=60;
    const int mod=1e9+7;
    int l[maxn],r[maxn];
    char ch[3*maxn];
    ll a[maxn];
    ll b[maxn];
    ll c[maxn],d[maxn];
    int pos[maxn];
    int main()
    {
        int t;
        cin>>t;
        while(t--)
        {
            int n;
            cin>>n;
            map<ll,ll>m1;
            map<ll,ll>m2;
            int tot1=0,tot2=0;
            ll mina=mod,minb=mod;
            for(int i=1;i<=n;i++)
                {
                    cin>>a[i];
                    mina=min(a[i],mina);
                }
            for(int i=1;i<=n;i++)
                {
                    cin>>b[i];
                    minb=min(b[i],minb);
                }
            ll cnt=0;
            for(int i=1;i<=n;i++)
            {
                int m1=a[i]-mina;
                int m2=b[i]-minb;
                if(m1>m2)
                {
                    cnt+=m2;
                    cnt+=m1-m2;
                }
                if(m1==m2)
                    cnt+=m1;
                if(m1<m2)
                {
                    cnt+=m1;
                    cnt+=m2-m1;
                }
            }
            cout<<cnt<<endl;
        }
    }

    C:http://codeforces.com/contest/1399/problem/C

    题意:

    有n个人想参加划船比赛。第i个参与者的权重是wi。

    只有两人组成的团队可以参加比赛。

    如果有k个团队(a1,b1),(a2,b2),…,(ak,bk),其中ai是第i个团队的第一个参与者的权重,bi是第二个团队的权重第i个团队的参与者,则必须满足条件a1 + b1 = a2 + b2 =⋯= ak + bk = s,其中s是每个团队的总权重。问有多少个团队可以参赛。

    解析:

    n==50,直接三重for暴力遍历每一个和值即可。

    先统计不同的两两和,然后对它们进行暴力枚举,看每一个值能组成多少团队,取最大即可。

    #include<iostream>
    #include<cstring>
    #include<algorithm>
    #include<stack>
    #include<map>
    using namespace std;
    typedef long long ll;
    const int maxn=60;
    const int mod=1e9+7;
    int l[maxn],r[maxn];
    char ch[3*maxn];
    int a[maxn];
    int b[8*maxn];
    int vis[maxn];
    ll c[maxn],d[maxn];
    int pos[maxn];
    int main()
    {
        int t;
        cin>>t;
        while(t--)
        {
            memset(vis,0,sizeof(vis));
            int n;
            cin>>n;
            for(int i=1;i<=n;i++)
                {
                    cin>>a[i];
                }
            int tot=0;
            map<int,int>m1;
            for(int i=1;i<=n;i++)
            {
                for(int j=i+1;j<=n;j++)
                {
                    int md=a[i]+a[j];
                    if(!m1[md])
                        b[tot++]=md;
                    m1[md]=1;
                }
            }
            int maxx=0;
            for(int i=0;i<tot;i++)
            {
                memset(vis,0,sizeof(vis));
                int cnt=0;
                int md=b[i];
                for(int j=1;j<=n;j++)
                {
                    for(int c=j+1;c<=n;c++)
                    {
                        int md2=a[j]+a[c];
                        if(!vis[j]&&!vis[c]&&md2==md)
                        {
                            cnt++;
                            vis[j]=1;
                            vis[c]=1;
                        }
                    }
                }
                maxx=max(maxx,cnt);
            }
            cout<<maxx<<endl;
        }
    }

    D:http://codeforces.com/contest/1399/problem/D

    题意:

    给定一个字符串由0/1组成,问最少有几个字符串是01间隔的(010101……或者101010……)。输出最少的个数和每个字符在第几个子字符串。

    解析:

    是存在贪心思想的。

    因为要想个数更少,肯定对于遍历到的每个0,要接到它之前已经存在的0101...上,而不是另开一个新子串,只有之前没得接的时候,才需要另开新子串。

    用到两个队列,一个是stack st[2],用来存以0/1结尾的符合条件的子序列编号。

    vector用来存每个字符属于第几个子串。

    接下来看注释吧:

    #include<iostream>
    #include<stack>
    #include<vector>
    using namespace std;
    typedef long long ll;
    int main()
    {
        int t;
        cin>>t;
        while(t--)
        {
            int n;
            cin>>n;
            string s;
            cin>>s;
            stack<int>st[2];
            vector<int>vv;
            int len=s.length();
            int all=1;
            for(int i=0;i<len;i++)
            {
                int now=s[i]-'0';
                if(st[now^1].empty())    //now对应的字符,如果没得接,就新开一个子串 
                {
                    st[now^1].push(all++);
                }
                int top=st[now^1].top();    //找到s[i]可以接的子串编号 
                vv.push_back(top);        //存入s[i]所属子串编号 
                st[now^1].pop();    // 现在的第top子串,已经接上了s[i],那么它的末尾就变了, 0->1/1->0,所以要把top传过去 
                st[now].push(top);     
            }
            all--;
            cout<<all<<endl;
            for(int i=0;i<vv.size();i++)
                cout<<vv[i]<<" ";
                cout<<endl;
        }
    }
  • 相关阅读:
    Linux 文件排序
    ubuntu18.04 美化桌面
    git clone 加速
    ubunutu下图像编辑器安装
    vue.js实战教程 https://www.jb51.net/Special/978.htm
    原生JS实现多条件筛选
    php结合js实现多条件组合查询
    js前端 多条件筛选查询
    JS 判断字符串是否全部为数字
    GET请求中URL的最大长度限制总结
  • 原文地址:https://www.cnblogs.com/liyexin/p/13449355.html
Copyright © 2011-2022 走看看