zoukankan      html  css  js  c++  java
  • Codeforces Round #258 (Div. 2)-(A,B,C,D,E)

    http://blog.csdn.net/rowanhaoa/article/details/38116713

    A:Game With Sticks

    水题。。

    每次操作,都会拿走一个横行,一个竖行。

    所以一共会操作min(横行,竖行)次。

    #include<stdio.h>
    #include<iostream>
    #include<stdlib.h>
    #include<string.h>
    #include<algorithm>
    #include<vector>
    #include<math.h>
    #include<map>
    #pragma comment(linker, "/STACK:1024000000,1024000000")
    using namespace std;
    #define mem(a,b) (memset(a),b,sizeof(a))
    #define lmin 1
    #define rmax n
    #define lson l,(l+r)/2,rt<<1
    #define rson (l+r)/2+1,r,rt<<1|1
    #define root lmin,rmax,1
    #define now l,r,rt
    #define int_now int l,int r,int rt
    #define INF 99999999
    #define LL __int64
    #define mod 1000000009
    #define eps 1e-6
    #define zero(x) (fabs(x)<eps?0:x)
    #define maxn 330000
    int main()
    {
        int n,m;
        while(~scanf("%d%d",&n,&m))
        {
            int y=min(n,m);
            if(y%2)cout<<"Akshat"<<endl;
            else cout<<"Malvika"<<endl;
        }
        return 0;
    }
    B:Sort the Array

    给数组中的每个数字标号,标记他应该出如今哪一个位置。

    然后从头往后找,假设当前位置的数字不是应该在这个位置的数字。

    那么就找到应该在这个位置的数字的位置,然后翻转。

    假设还不是按顺序排的话,就输出no。否则输出yes。

    #include<stdio.h>
    #include<iostream>
    #include<stdlib.h>
    #include<string.h>
    #include<algorithm>
    #include<vector>
    #include<math.h>
    #include<map>
    #pragma comment(linker, "/STACK:1024000000,1024000000")
    using namespace std;
    #define mem(a,b) (memset(a),b,sizeof(a))
    #define lmin 1
    #define rmax n
    #define lson l,(l+r)/2,rt<<1
    #define rson (l+r)/2+1,r,rt<<1|1
    #define root lmin,rmax,1
    #define now l,r,rt
    #define int_now int l,int r,int rt
    #define INF 99999999
    #define LL __int64
    #define mod 1000000009
    #define eps 1e-6
    #define zero(x) (fabs(x)<eps?0:x)
    #define maxn 110000
    struct list
    {
        int x;
        int id;
        int y;
    }node[maxn];
    int cmp1(list a,list b)
    {
        return a.x<b.x;
    }
    int cmp2(list a,list b)
    {
        return a.id<b.id;
    }
    int main()
    {
        int n,m;
        while(~scanf("%d",&n))
        {
            for(int i=1;i<=n;i++)
            {
                scanf("%d",&node[i].x);
                node[i].id=i;
            }
            sort(node+1,node+n+1,cmp1);
            for(int i=1;i<=n;i++)node[i].y=i;
            sort(node+1,node+n+1,cmp2);
            int st,ed,i;
            st=ed=-1;
            for(i=1;i<=n;i++)
            {
                if(node[i].y!=i)
                {
                    if(st==-1)
                    {
                        int j,k;
                        for(j=i+1;j<=n;j++)
                        {
                            if(node[j].y==i)break;
                        }
                        for(k=j;k>=i;k--)
                        {
                            if(node[k].y!=i+(j-k))break;
                        }
                        if(k>=i)break;
                        st=i;
                        ed=j;
                        i=j+1;
                    }
                    else break;
                }
            }
            if(i<=n)cout<<"no"<<endl;
            else
            {
                cout<<"yes"<<endl;
                if(st!=-1)cout<<st<<" "<<ed<<endl;
                else cout<<"1 1"<<endl;
            }
        }
        return 0;
    }
    C:Predict Outcome of the Game

    枚举两个差值的正负号。

    对于每一种情况:

    能够算出A,B,C最少赢几个球。

    然后看看当前的赢球数是不是符合K。

    然后看一下差值能否够用(n-k)消除掉。

    #include<stdio.h>
    #include<iostream>
    #include<stdlib.h>
    #include<string.h>
    #include<algorithm>
    #include<vector>
    #include<math.h>
    #include<map>
    #pragma comment(linker, "/STACK:1024000000,1024000000")
    using namespace std;
    #define mem(a,b) (memset(a),b,sizeof(a))
    #define lmin 1
    #define rmax n
    #define lson l,(l+r)/2,rt<<1
    #define rson (l+r)/2+1,r,rt<<1|1
    #define root lmin,rmax,1
    #define now l,r,rt
    #define int_now int l,int r,int rt
    #define INF 99999999
    #define LL __int64
    #define mod 1000000009
    #define eps 1e-6
    #define zero(x) (fabs(x)<eps?0:x)
    #define maxn 110000
    struct list
    {
        int x;
        int id;
        int y;
    }node[maxn];
    int cmp1(list a,list b)
    {
        return a.x<b.x;
    }
    int cmp2(list a,list b)
    {
        return a.id<b.id;
    }
    int pan(LL n,LL k,LL d1,LL d2)
    {
        LL a,b,c;
        a=0;
        b=a+d1;
        c=b+d2;
        LL d;
        d=min(a,min(b,c));
        if(d<0)
        {
            d=-d;
            a+=d;
            b+=d;
            c+=d;
        }
        d=max(a,max(b,c));
        LL cha=0;
        cha=a+b+c;
        cha=k-cha;
        if(cha<0)return 0;
        if(cha%3)return 0;
        cha=0;
        cha+=d-a;
        cha+=d-b;
        cha+=d-c;
        LL cun=n-k;
        cun=cun-cha;
        if(cun<0)return 0;
        if(cun%3==0)
        {
         //   cout<<n<<" "<<k<<" "<<d1<<" "<<d2<<endl;
            return 1;
        }
        else return 0;
    }
    void dos()
    {
        LL n,k,d1,d2;
        cin>>n>>k>>d1>>d2;
        LL a,b,c;
        a=0;
        if(pan(n,k,d1,d2))
        {
            cout<<"yes"<<endl;
            return;
        }
        if(pan(n,k,-d1,d2))
        {
            cout<<"yes"<<endl;
            return;
        }
        if(pan(n,k,d1,-d2))
        {
            cout<<"yes"<<endl;
            return;
        }
        if(pan(n,k,-d1,-d2))
        {
            cout<<"yes"<<endl;
            return;
        }
        cout<<"no"<<endl;
    }
    int main()
    {
        int t;
        LL n,k,d1,d2;
        while(~scanf("%d",&t))
        {
            while(t--)
            {
                dos();
            }
        }
        return 0;
    }
    D:Count Good Substrings

    假如字符串为:abbabbbaaa

    我们把这个字符串例如以下记录: 

         字符串: a b a b a

    数组num :1 2 1 3  3

    数组的每一项代表这个字符串这个位置的字符是由几个字符压缩成的。

    对于回文串的两边都是a的情况:

    预处理从起点走奇数步可到达多少a。走偶数步,可到达多少a。

    然后从第一个a往后走,可在O(1)的复杂度内得出当前a的为回文串的左边。一共同拥有几个奇数子串。几个偶数子串。

    对于回文串的两边都是b的情况,类似与两边都是a的情况。

    #include<stdio.h>
    #include<iostream>
    #include<stdlib.h>
    #include<string.h>
    #include<algorithm>
    #include<vector>
    #include<math.h>
    #include<map>
    #pragma comment(linker, "/STACK:1024000000,1024000000")
    using namespace std;
    #define mem(a,b) (memset(a),b,sizeof(a))
    #define lmin 1
    #define rmax n
    #define lson l,(l+r)/2,rt<<1
    #define rson (l+r)/2+1,r,rt<<1|1
    #define root lmin,rmax,1
    #define now l,r,rt
    #define int_now int l,int r,int rt
    #define INF 99999999
    #define LL __int64
    #define mod 1000000009
    #define eps 1e-6
    #define zero(x) (fabs(x)<eps?0:x)
    #define maxn 110000
    LL a[maxn];
    char str[maxn];
    vector<char>vec;
    int num[maxn];
    LL s1,s2;
    LL cal(int x,int y)
    {
        if(x<0)return 0;
        LL a1,an,n;
        if(y==1)
        {
            if(x<2)return 0;
            an=x-1;
            if(x%2)a1=2;
            else a1=1;
            n=(an-a1)/2+1;
            return n*(a1+an)/(LL)2;
        }
        else
        {
            an=x;
            if(x%2)a1=1;
            else a1=2;
            n=(an-a1)/2+1;
            return n*(a1+an)/(LL)2;
        }
    }
    void dos(int x)
    {
        int n=vec.size();
        LL even,odd;
        even=odd=0;
        LL sum=0;
        for(int i=1; i<=n; i++)
        {
            if(i%2==x)
            {
                LL a,b;
                a=num[i]/2;
                b=num[i]-a;
                if(sum%2)swap(a,b);
                even+=a;//偶
                odd+=b;//奇
            }
            sum+=num[i];
        }
        sum=0;
        for(int i=x;i<=n;i+=2)
        {
            LL a,b;
            a=num[i]/2;
            b=num[i]-a;
            if(sum%2)swap(even,odd);
            sum=0;
            even-=a;
            odd-=b;
            sum+=num[i];
            if(sum%2)swap(even,odd);
            sum=0;
            s1+=b*odd;
            s1+=a*even;
            s2+=b*even;
            s2+=a*odd;
            s1+=cal(num[i],1);
            s2+=cal(num[i],2);
            sum+=num[i+1];
        }
    }
    int main()
    {
        int n;
        LL s;
        while(~scanf("%s",str))
        {
            vec.clear();
            int len=strlen(str);
            int s=1;
            for(int i=1; i<len; i++)
            {
                if(str[i]!=str[i-1])
                {
                    vec.push_back(str[i-1]);
                    num[vec.size()]=s;
                    s=1;
                }
                else s++;
            }
            vec.push_back(str[len-1]);
            num[vec.size()]=s;
            s1=s2=0;
            dos(1);
            dos(0);
            cout<<s1<<" "<<s2<<endl;
        }
        return 0;
    }

    E:Devu and Flowers

    做这个题目出了一些莫名其妙的问题。

    做法:

    假设每个每一种花都有无限个。非常明显,有C(s+n-1,n-1)种取法。

    假设某种花取x个以上,那么就有C(s+n-1-x-1,n-1)种取法。

    所以就用到容斥:

    #include<stdio.h>
    #include<iostream>
    #include<stdlib.h>
    #include<string.h>
    #include<algorithm>
    #include<vector>
    #include<math.h>
    #include<map>
    using namespace std;
    #define maxn 21
    #define LL __int64
    #define mod 1000000007
    LL num[21];
    LL inv[21];
    void gcd(LL a, LL b, LL& d, LL& x, LL& y) {
        if(!b){ d = a; x = 1; y = 0; }
        else{ gcd(b, a%b, d, y, x); y -= x*(a/b); }
    }
    
    LL getInv(LL a, LL n) {
        LL d, x, y;
        gcd(a, n, d, x, y);
        return d == 1 ? ( x + n ) % n : -1;
    }
    LL com(LL n,LL m)
    {
    
        if(n<m)return 0;
        LL ans;
        ans=1;
        for(LL i=n;i>=(n-m+1);i--)
        {
            ans=ans*(i%mod)%mod;
            ans=ans*inv[n-i+1]%mod;
        }
        return ans;
    }
    int main()
    {
        LL n,s;
        for(int i=1;i<=20;i++)inv[i]=getInv(i,mod);
        while(~scanf("%I64d%I64d",&n,&s))
        {
            LL r=0;
            int m=n;
            for(int i=0;i<m;i++)
            {
                scanf("%I64d",&num[i]);
            }
            LL ans=com(s+n-1,n-1);
            for(int i=1;i<(1<<m);i++)
            {
                int x=0;
                r=0;
                for(int j=0;j<m;j++)
                {
                    if(i&(1<<j))
                    {
                        x++;
                        r+=num[j]+1;
                    }
                }
                if(x&1)
                {
                    ans-=com(s-r+n-1,n-1);
                    ans=(ans%mod+mod)%mod;
                }
                else
                {
                    ans+=com(s-r+n-1,n-1);
                    ans=(ans%mod+mod)%mod;
                }
            }
            cout<<ans<<endl;
        }
        return 0;
    }
    














  • 相关阅读:
    编码转换,基础补充,深浅拷贝,id is == ,代码块(了解),小数据池(了解)
    字典(dict),字典的嵌套,集合(set)
    列表,列表的增删改查,列表的嵌套,range
    整数,布尔值,字符串,字符串详解.
    [小明学Shader]4.自定义光照----RampTexture
    [小明学Shader]3.自定义光照,半拉姆伯特
    [小明学Shader]2.理解Shader和Material的关系
    [小明学Shader]1.Diffuse
    [UGUI]你说UnityEngine.UI.Button是怎么通过拖动来增加OnClick的监听器的呢?
    [小明也得懂架构]1.架构初探
  • 原文地址:https://www.cnblogs.com/cynchanpin/p/6704176.html
Copyright © 2011-2022 走看看