首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 其他教程 > 其他相关 >

Codeforces Round #173 (Div. 二) 解题报告

2013-03-21 
Codeforces Round #173 (Div. 2)解题报告 题目链接:http://codeforces.com/contest/282 A题Bit题意:求出通

Codeforces Round #173 (Div. 2) 解题报告

 

题目链接:

http://codeforces.com/contest/282

 

A题   Bit++

题意:求出通过一系列自增自减运算最后变量的值。不用考虑前后。水题。

#include<iostream>#include<cmath>#include<cstdio>#include<cstdlib>#include<string>#include<cstring>#include<algorithm>#include<vector>#include<map>#include<stack>#include<queue>#define eps 1e-6#define INF (1<<20)#define PI acos(-1.0)using namespace std;int main(){    int n;    char save[5];    while(scanf("%d",&n)!=EOF)    {        int x=0;        while(n--)        {            scanf("%s",save);            if(save[0]=='X')            {                if(save[1]=='-')                    x--;                else                    x++;            }            else            {                if(save[0]=='+')                    x++;                else                    x--;            }        }        printf("%d\n",x);    }    return 0;}


 

B题  Painting Eggs

题意:n个蛋,两个人对每一个蛋涂漆都有一个价格,要使蛋都涂完,且两个人的付费差不超过500,问怎样分配这n个蛋。

解题思路:对每一个蛋进行贪心,如果如果给第一个人使得两人的差价低于给第二个人两人的差价,则把该蛋分给第一个人。

代码:

#include<iostream>#include<cmath>#include<cstdio>#include<cstdlib>#include<string>#include<cstring>#include<algorithm>#include<vector>#include<map>#include<stack>#include<queue>#define eps 1e-6#define INF (1<<20)#define PI acos(-1.0)using namespace std;char ans[1100000];int main(){    int n;    while(scanf("%d",&n)!=EOF)    {        int a=0,b=0,num=0;        int temp1,temp2;        while(n--)        {            scanf("%d%d",&temp1,&temp2);            if(abs(a+temp1-b)<abs(b+temp2-a))             {                 ans[num++]='A';                 a+=temp1;             }            else            {                ans[num++]='G';                b+=temp2;            }        }        ans[num]='\0';        if(abs(a-b)<=500)            printf("%s\n",ans);        else            printf("-1\n");    }    return 0;}


 

C题   XOR and OR

题意:给两个0、1组成的字符串,可以从第一个字符串任取两个相邻的字符,通过抑或和或运算得到两个数代替取出的两个字符,问经过多次这样的操作以后能否得到第二个字符。

解题思路:找规律。11<->01或10   00<->00  它们之间是等价的。所以只要两串都含1且长度相等,一定可以转换。

代码:

#include<iostream>#include<cmath>#include<cstdio>#include<cstdlib>#include<string>#include<cstring>#include<algorithm>#include<vector>#include<map>#include<stack>#include<queue>#define eps 1e-6#define INF (1<<20)#define PI acos(-1.0)using namespace std;char save1[1100000],save2[1100000];int main(){    while(scanf("%s%s",save1,save2)!=EOF)    {        bool flag1=false,flag2=false;        int len1=strlen(save1),len2=strlen(save2);        if(len1!=len2||(len1==1&&strcmp(save1,save2)))        {            printf("NO\n");            continue;        }        for(int i=0;i<len1;i++)            if(save1[i]=='1')            {                flag1=true;                break;            }        for(int i=0;i<len2;i++)            if(save2[i]=='1')            {                flag2=true;                break;            }        if((flag1==false&&flag2==true)||(flag1==true&&flag2==false))            printf("NO\n");        else            printf("YES\n");    }    return 0;}


 

D题: Yet Another Number Game

题意:有n堆数(n<=3),有两种操作,操作一:把某一堆数减一个不大于它的数。操作二:把每一堆都减一个数m(1<=m<=min(所有数))。两人依次操作,每人都完美表现,最后不能做操作的输,问谁赢。

解题思路:当n=1时,如果数量大于0则先胜,否则先负。

当n=2时,Wythoff game.可以直接用公式,也可以用动归把所有的情况都列出来。

当n=3时,Nim game. 如果三个数的抑或为0(奇异点),则必输,否则为赢。

代码:

#include<iostream>#include<cmath>#include<cstdio>#include<cstdlib>#include<string>#include<cstring>#include<algorithm>#include<vector>#include<map>#include<stack>#include<queue>#define eps 1e-6#define INF (1<<20)#define PI acos(-1.0)using namespace std;int main(){    int n,a,b,c;    while(scanf("%d",&n)!=EOF)    {       if(n==1)       {            scanf("%d",&a);            if(a)                printf("BitLGM\n");            else                printf("BitAryo\n");       }             if(n==2)       {           scanf("%d%d",&a,&b);           bool dp[350][350];           memset(dp,false,sizeof(dp));           for(int i=1;i<=a;i++)                dp[i][0]=true;           for(int j=1;j<=b;j++)                dp[0][j]=true;           for(int i=1;i<=a;i++)            for(int j=1;j<=b;j++)            {                int flag=0;                if(i==j)  //采用第二种方法                {                    dp[i][j]=true;                    continue;                }                else                {                    int Min=min(i,j);                    for(int k=1;k<=Min;k++)                        if(dp[i-k][j-k]==false)                        {                            dp[i][j]=true;                            flag=1;                            break;                        }                }                if(flag==1)                    continue;                for(int k=1;k<=i;k++)  //采用第一种方法                    if(dp[i-k][j]==false)                    {                        flag=1;                        dp[i][j]=true;                        break;                    }                if(flag==0)                {                    for(int k=1;k<=j;k++)                        if(dp[i][j-k]==false)                        {                            dp[i][j]=true;                            flag=1;                            break;                        }                }            }            if(dp[a][b]==true)                printf("BitLGM\n");            else                printf("BitAryo\n");       }       if(n==3)       {            scanf("%d%d%d",&a,&b,&c);            if(a^b^c)                printf("BitLGM\n");            else                printf("BitAryo\n");       }    }    return 0;}


E题  Sausage Maximization

题意:给n(n<=10^5)个数,然后让你求出最大的前p个数和后q个数的抑或和。

解题思路:用Trie树。贪心选择最大值。

//trie树与贪心#include<iostream>#include<cmath>#include<cstdio>#include<cstdlib>#include<string>#include<cstring>#include<algorithm>#include<vector>#include<map>#include<stack>#include<queue>#define eps 1e-6#define INF (1<<20)#define PI acos(-1.0)using namespace std;struct Node{    struct Node * son[2];    long long data;}*root;long long save[110000];struct Node * create(){    struct Node *p=(struct Node *)malloc(sizeof(struct Node));    p->data=0;    p->son[0]=p->son[1]=NULL;    return p;}void insert(struct Node *cur,long long num){    int bit[50];    struct Node *temp=cur;    for(int i=0;i<=40;i++)        bit[i]=1&(num>>i);    for(int i=40;i>=0;i--) //都保存为50位,无所谓是从低位还是从高位    {        if(temp->son[bit[i]]==NULL)            temp->son[bit[i]]=create();        temp=temp->son[bit[i]];    }    temp->data=num;}long long  query(struct Node *cur ,long long num){    int bit[50];    struct Node *temp=cur;    for(int i=0;i<=40;i++)        bit[i]=1&(num>>i);    for(int i=40;i>=0;i--)  //从高位开始,贪心算法    {        if(temp->son[bit[i]^1])  //如果bit[i]=0 则应该选择son[1];如果bit[i]=1,则应该选择son[0]            temp=temp->son[bit[i]^1]; //1与其他抑或得到它的反数        else            temp=temp->son[bit[i]];    }    return num^(temp->data);}int main(){    int n;    while(cin>>n)    {        root=create();        long long sum=0,ans=0;        for(int i=1;i<=n;i++)        {            cin>>save[i];            sum^=save[i];            insert(root,sum);            ans=max(ans,sum); //此时后缀为空        }        sum=0;        for(int i=n;i>=1;i--)        {            sum^=save[i];            ans=max(ans,query(root,sum));        }        cout<<ans<<endl;    }    return 0;}


 

 

 

 

 

热点排行