poj 3185

来源:互联网 发布:class c语言 编辑:程序博客网 时间:2024/05/22 13:41

这个题可以用高斯消元来解,那就是水题

不过有很多有意思的解法,例举一二



1贪心:


从左到右枚举一边(每个硬币翻还是不翻仅由其前面的硬币的状态决定)

但是有这种情况:


110000000...(省略n多个0)


可证,反而是从第一个开始翻就比较好


这样就从右再向左枚举一边

两次枚举,得结果


也可这样看,枚举第一个硬币翻还是不翻


代码一:

#include <iostream>#include <cstring>#include <string>#include <cstdio>using namespace std;int num[40]={0},nc[40]={0};int deal(int a){    if(a==0)return 1;    if(a==1)return 0;}int Min(int a,int b){    if(a<b)return a;    return b;}int main(){    int tmp1,tmp2;    int cnt=200;    for(int i=1;i<=20;i++){        scanf("%d",&num[i]);        nc[i]=num[i];    }    tmp1=0;// 1fanzhuan    //num[1]=!num[1];    for(int i=1;i<=20;i++){        if(num[i-1]){            num[i-1]=0;            num[i]=deal(num[i]);            num[i+1]=deal(num[i+1]);            tmp1++;        }    }    tmp2=0;//1bufanzhuan    //nc[1]=nc[1];    for(int i=19;i>=0;i--){        if(nc[i+1]){            nc[i+1]=0;            nc[i]=deal(nc[i]);            nc[i-1]=deal(nc[i-1]);            tmp2++;        }    }    cnt=Min(tmp1,tmp2);    printf("%d\n",cnt);}

代码二:

#include <iostream>using namespace std;int bowl[25]={0},flip[25]={0};int main(){int i,cnt=100,tmp;for (i=1;i<21;i++)cin >> bowl[i];flip[1] = tmp = 1;//翻第一个for (i=2;i<21;i++)if ( flip[i] = (flip[i-2]^flip[i-1]^bowl[i-1]) )tmp++;if ( tmp<cnt && (flip[19]^flip[20]^bowl[20])==0 )cnt = tmp;flip[1] = tmp = 0;//不翻第一个for (i=2;i<21;i++)if ( flip[i] = (flip[i-2]^flip[i-1]^bowl[i-1]) )tmp++;if ( tmp<cnt  && (flip[19]^flip[20]^bowl[20])==0 )cnt = tmp;cout << cnt << endl;return 0;}


2暴搜:

详见代码


#include <cstdio>#include <cstring>#include <iostream>using namespace std;int num[27],step,flag;int range(){    int i;    for(i=0;i<20;i++)        if(num[i]==1)            return 0;    return 1;}void turn(int i){    num[i]=!num[i];    if(i>0)        num[i-1]=!num[i-1];    if(i<19)num[i+1]=!num[i+1];}void DFS(int i,int dp){    if(step==dp){        flag=range();//flag=1 fail        return;    }    if(i>=20||flag)return;    turn(i);    DFS(i+1,dp+1);//i zhuan    turn(i);    DFS(i+1,dp);//i buzhuan}int main(){    int i;    for(i=0;i<20;i++)        scanf("%d",&num[i]);    for(step=0;step<20;step++)    {        flag=0;        DFS(0,0);        if(flag)break;    }    printf("%d\n",step);    return 0;}



0 0