首页 > 代码库 > HDU 2209 翻纸牌游戏(dfs)
HDU 2209 翻纸牌游戏(dfs)
翻纸牌游戏
Time Limit: 9000/3000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 2180 Accepted Submission(s): 787
Problem Description
有一种纸牌游戏,很有意思,给你N张纸牌,一字排开,纸牌有正反两面,开始的纸牌可能是一种乱的状态(有些朝正,有些朝反),现在你需要整理这些纸牌。但是麻烦的是,每当你翻一张纸牌(由正翻到反,或者有反翻到正)时,他左右两张纸牌(最左边和最右边的纸牌,只会影响附近一张)也必须跟着翻动,现在给你一个乱的状态,问你能否把他们整理好,使得每张纸牌都正面朝上,如果可以,最少需要多少次操作。
Input
有多个case,每个case输入一行01符号串(长度不超过20),1表示反面朝上,0表示正面朝上。
Output
对于每组case,如果可以翻,输出最少需要翻动的次数,否则输出NO。
Sample Input
01
011
Sample Output
NO
1
每张牌由三张牌决定(不包括首位两张牌),对于第 i 张牌,若不考虑其后面一张牌只考虑其前面一张牌,那么由第i-1牌的状态可以决定第 i 张牌翻不翻,(由于翻牌时对一张牌翻多次没必要,所以每张牌只是两种情况:翻或者不翻),若第i-1张牌是反面,那么把i-1、i、i+1都翻一次,否则都不翻 ,向后(对i+1)进行前面操作,显然初始状态是 第 1 张牌翻还是不翻,对这两种状态都进行一次上述操作,看哪种状态下可以得到我们所需要的状态。 结束时只判断最后一张牌是否是正面即可(第 i 张牌前面的所有牌在 i 之前的操作中全变成正面朝上)。
代码:
1 #include <cstdio> 2 #include <cstring> 3 #include <algorithm> 4 #include <iostream> 5 using namespace std; 6 #define inf 999999999 7 8 int a[22]; 9 char c[22];10 int n;11 12 13 int dfs(int k,int step){14 15 if(k>=n){16 return a[k-1]?inf:step;17 18 }19 if(a[k-1]){ //若第K张牌前面一张牌为反面,那么需要翻第k张牌使得第k-1张牌正面朝上 20 a[k-1]=0;21 a[k]=!a[k];22 a[k+1]=!a[k+1];23 step++;24 }25 return dfs(k+1,step);26 }27 28 main()29 {30 int i, j;31 while(scanf("%s",c)!=EOF){32 n=strlen(c);33 for(i=0;i<n;i++) a[i]=c[i]-‘0‘;34 a[0]=!a[0];a[1]=!a[1]; //翻第一张牌 35 int num=inf;36 37 num=min(num,dfs(1,1)); 38 for(i=0;i<n;i++) a[i]=c[i]-‘0‘; 39 num=min(num,dfs(1,0)); //不翻第一张牌 40 if(num==inf) printf("NO\n");41 else printf("%d\n",num); 42 }43 }
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。