zoukankan      html  css  js  c++  java
  • Codeforces Round #677 (Div. 3)(A->E(排列组合))

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

    解析:

    直接手写个表,一个一个算就行了。

    #include<bits/stdc++.h>
    #define ll long long
    using namespace std;
    const int maxn = 1e5 + 95;
    int num[9999]={0,1,11,111,1111,2,22,222,2222,3,33,333,3333,4,44,444,4444,5,55,555,5555,6,66,666,6666,7,77,777,7777,
    8,88,888,8888,9,99,999,9999};
    int main()
    {
        int t;
        cin>>t;
        while(t--)
        {
            int x;
            cin>>x;
            int cnt=0;
            for(int i=1;;i++)
            {
                if(i%4==1)
                    cnt++;
                else if(i%4==2)
                    cnt+=2;
                else if(i%4==3)
                    cnt+=3;
                else
                     cnt+=4;
                if(num[i]==x)
                {
                    break;
                }
            }
            cout<<cnt<<endl;
        }
        
    }

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

    题意:

    对于[L,R]如果里面全是1,而且L-1是0或R+1是0,就可以整体左移或右移。

    求使整个数组无0间隔的最小移动数。

    解析:

    先找到第一个1,从这里开始遍历

    如果这一位是1,下一位是0,就往后找1,找到就加间距

    #include<bits/stdc++.h>
    #define ll long long
    using namespace std;
    const int maxn = 1e5 + 95;
    int num[9999]={0,1,11,111,1111,2,22,222,2222,3,33,333,3333,4,44,444,4444,5,55,555,5555,6,66,666,6666,7,77,777,7777,
    8,88,888,8888,9,99,999,9999};
    int a[66];
    int main()
    {
        int t;
        cin>>t;
        while(t--)
        {
            int n;
            cin>>n;
            for(int i=1;i<=n;i++)
                cin>>a[i];
            int maxx=0;
            int ok=0;
            int id;
            for(int i=1;i<=n;i++)
            {
                if(a[i]==1)
                {
                    id=i;break;
                }
            }
            int sum=0;
            for(int i=id;i<=n;i++)
            {
                if(a[i]==1&&a[i+1]==0)
                {
                    int mdid;
                    for(int j=i+2;j<=n;j++)
                    {
                        if(a[j]==1)
                        {
                            sum+=j-i-1;
                            break;    
                        }
                    }
                }
            }
            cout<<sum<<endl;
        }
        
    }

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

    题意:

    如果一个食人鱼,比左边或右边大,就可以吃掉左边或右边那条,自身+1

    是否存在这么一条食人鱼,每次都让它吃,使得最后只剩它一条?

    解析:

    全相等肯定不存在。否则一定存在

    先找出最大值,再遍历一次,如果存在某个值等于最大值,而且左边或右边鱼与它不相等,就输出它即可。

    #include<bits/stdc++.h>
    #define ll long long
    using namespace std;
    const int maxn = 3e5 + 95;
    int num[9999]={0,1,11,111,1111,2,22,222,2222,3,33,333,3333,4,44,444,4444,5,55,555,5555,6,66,666,6666,7,77,777,7777,
    8,88,888,8888,9,99,999,9999};
    ll a[maxn];
    int main()
    {
        int t;
        cin>>t;
        while(t--)
        {
            int n;
            cin>>n;
            cin>>a[1];
            ll maxx=a[1];
            int ok=0;
            for(int i=2;i<=n;i++)
            {
                cin>>a[i];
                maxx=max(maxx,a[i]);
                if(a[i]!=a[i-1])
                    ok=1;
            }
            if(!ok)
                cout<<"-1"<<endl;
            else
            {
                int idx;
                a[n+1]=a[n];
                for(int i=n;i>=1;i--)
                {
                    if(a[i]==maxx&&(a[i]!=a[i-1]||a[i]!=a[i+1]))
                    {
                        idx=i;
                        break;
                    }
                }
                cout<<idx<<endl;
            }
            
        }
        
    }

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

    题意:

    n个组,ai表示其所属帮派。

    用n-1条边,使得每个组之间可以互相到达。如果两个同帮派直接相连,那么就会发生冲突。

    是否存在一种连接方式,避免这种情况?

    解析:

    1:全都属于一个帮派,肯定不存在。

    2:想象成卫星图

    找两个不相等的ai,连一起,其他的ai往它俩上连即可。

    #include<bits/stdc++.h>
    #define ll long long
    using namespace std;
    const int maxn = 5e3 + 95;
    int num[9999]={0,1,11,111,1111,2,22,222,2222,3,33,333,3333,4,44,444,4444,5,55,555,5555,6,66,666,6666,7,77,777,7777,
    8,88,888,8888,9,99,999,9999};
    ll a[maxn];
    bool ac1(int n)
    {
        
    }
    int main()
    {
        int t;
        cin>>t;
        while(t--)
        {
            int n;
            cin>>n;
            int ok=0;
            for(int i=1;i<=n;i++)
            {
                cin>>a[i];
            }
            for(int i=2;i<=n;i++)
            {
                if(a[i]!=a[i-1])
                {
                    ok=1;break;
                }
            }
            if(!ok)
                cout<<"NO"<<endl;
            else
            {
                int id;
                for(int i=1;i<n;i++)
                {
                    if(a[i]!=a[i+1])
                    {
                        id=i;
                        break;
                    }
                }
                int idl=id,idr=id+1;
                cout<<"YES"<<endl;
                for(int i=1;i<=n;i++)
                {
                    if(i==idl)
                        continue;
                    if(a[i]!=a[idl])
                    {
                        cout<<i<<" "<<idl<<endl;
                    }
                    else if(a[i]!=a[idr])
                    {
                        cout<<i<<" "<<idr<<endl;
                    }
                }
            }
        }
        
    }

    E:http://codeforces.com/contest/1433/problem/E

    题意:

    n个人,n为偶数

    分成两组,每组围成一个圈跳舞,问一共有多少种组合方式。

    注意:1,2   3,4 和  3,4   1,2是同样的分组方式

    1,2,3,4和2,3,4,1是同一种跳舞排列方式。

    解析:

    首先,n个人中选两个,有C(n,n/2)种,/2即为分组种类数。

    分完组,接下来看圈:

    先把跳舞人看成线性,那么对于1,2,3,4 |  2, 3, 4, 1| 3, 4, 1, 2 。只要每个人的相对位置不变,那么这个1不管在什么位置,都是同一种排列方式。

    所以对于一种排列方式,需要固定一个参照点,这个点不要动,其他的随意放即可。

    对于一个圈,n/2个人,先固定一个参照点,那么还剩n/2-1个人,所以有(n/2-1)! 种排列方式,而另一个圈还有 (n/2-1)! 种

    所以总的答案就是:C(n,n/2) * (n/2-1)! (n/2-1)!  / 2

    #include<bits/stdc++.h>
    #define ll long long
    using namespace std;
    const int maxn = 1e5 + 95;
    const int inf=999999999;
    int main()
    {
        ll n;
        cin>>n;
        ll sum=1;
        ll md=n;
        for(int i=1;i<=n/2;i++)
        {
            sum*=md;
            md--;
        }
        md=1;
        for(int i=1;i<=n/2;i++)
        {
            md*=i;
        }
        sum=sum/md;
        md=1;
        for(int i=1;i<=n/2-1;i++)
        {
            md*=i;
        }
        cout<<sum*md*md/2<<endl;
    }
  • 相关阅读:
    barnes-hut算法 && Fast Multipole Methods算法
    最大独立集问题-maximal independent set problem
    kernighan lin算法
    浅析Struts2中的OGNL和ValueStack
    Python框架之Django学习笔记(十四)
    C++抓网页/获取网页内容
    SpiderMonkey-让你的C++程序支持JavaScript脚本
    关于职位的解释---转CSDN的文章
    优雅的css写法
    linux
  • 原文地址:https://www.cnblogs.com/liyexin/p/13854938.html
Copyright © 2011-2022 走看看