Codeforces #228 div1

来源:互联网 发布:向日葵mac被控端 编辑:程序博客网 时间:2024/05/18 02:50

A.水题,二分答案瞎搞搞就行了

#include <stdio.h>#include <string.h>#include <algorithm>#include <vector>using namespace std;int a[105],n;bool cmp(int x,int y){    return x>y;}bool Check(int t){    vector<int> pile[105];    int k=0,cnt=0,i,j;    for (i=0;i<n;i++)    {        for (j=0;j<pile[k].size();j++)        {            if ((int)(pile[k][j]-pile[k].size()+j)<=-1)            {                break;            }        }        if (j<pile[k].size())        {            i--;            cnt++;            k=(k+1)%t;            if (cnt==t) return false;            continue;        }        cnt=0;        pile[k].push_back(a[i]);        k=(k+1)%t;    }    return true;}int main(){    int i,j,l,r;    scanf("%d",&n);    for (i=0;i<n;i++)    {        scanf("%d",&a[i]);    }    sort(a,a+n,cmp);    l=1;r=n;    while(l<=r)    {        int mid=(l+r)/2;        if (Check(mid)==true) r=mid-1;        else l=mid+1;    }    printf("%d\n",l);    return 0;}

B.构造一个三角形

      O

      /\

   O  O

   /\    /\

 O  O  O

 /\   /\   /\

O O O O

这样从第一行走,到第一行的点有2^0种走法,到第二行的点有2^1种走法,到第三行的点有2^2种走法……

然后把输入数据按照二进制分解,哪一位是一就从那一行牵一条路出来,最后加个源点汇点就好了

#include <stdio.h>#include <string.h>#include <algorithm>#include <vector>using namespace std;#define MAXN 30char map[1005][1005];int hash[35];int num[35];int main(){    int i,j,t,k,l;    scanf("%d",&t);    for (i=0;i<1000;i++)    {        for (j=0;j<1000;j++)        {            map[i][j]='N';        }    }    k=1;    for (i=2;;)    {        if (MAXN-k+1<0) break;        hash[MAXN-k+1]=i;        j=0;        if (i>2)        {            int tmp=hash[MAXN-k+2];            for (j=0;j<k;j++)            {                if (j==0 || j==k-1) map[i+j][tmp]=map[tmp][i+j]='Y';                else                {                    map[i+j][tmp]=map[tmp][i+j]='Y';                    tmp++;                    map[tmp][i+j]=map[i+j][tmp]='Y';                }                if (MAXN-k+1==0) map[i+j][0]=map[0][i+j]='Y';            }        }        i+=k;        k++;    }    int n=i,up=0;    while(t)    {        num[up++]=t%2;        t/=2;    }    for (i=0;i<up;i++)    {        if (num[i]==0) continue;        int tmp=hash[i];        for (j=i;j<MAXN;j++)        {            map[tmp][n]=map[n][tmp]='Y';            tmp=n;            n++;        }        map[n-1][1]=map[1][n-1]='Y';    }    printf("%d\n",n);    for (i=0;i<n;i++)    {        for (j=0;j<n;j++)        {            printf("%c",map[i][j]);        }        printf("\n");    }    return 0;}

C.因为如果某一个数特别大,两边肯定都要抢着拿,所以,先手只能拿到上半部分,后手只能拿到后半部分,如果是奇数中间剩下一个那就排个序从大到小两个人轮流拿了。

#include <stdio.h>#include <string.h>#include <algorithm>#include <vector>using namespace std;vector<int> pile[105];int last[105];bool cmp(int x,int y){    return x>y;}int main(){    int i,j,n,first=0,next=0,x,y,up=0;    scanf("%d",&n);    for (i=0;i<n;i++)    {        scanf("%d",&x);        for (j=0;j<x;j++)        {            scanf("%d",&y);            pile[i].push_back(y);        }    }    for (i=0;i<n;i++)    {        if (pile[i].size()%2==0)        {            for (j=0;j<pile[i].size()/2;j++) first+=pile[i][j];            for (;j<pile[i].size();j++) next+=pile[i][j];        }        else        {            for (j=0;j<pile[i].size()/2;j++) first+=pile[i][j];            last[up++]=pile[i][j];            for (j=j+1;j<pile[i].size();j++) next+=pile[i][j];        }    }    sort(last,last+up,cmp);    for (i=0;i<up;i++)    {        if (i%2==0) first+=last[i];        else next+=last[i];    }    printf("%d %d\n",first,next);    return 0;}


0 0