hdu 2209 -- 翻纸牌游戏

翻纸牌游戏

Time Limit: 9000/3000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 2086    Accepted Submission(s): 747


Problem Description
有 一种纸牌游戏,很有意思,给你N张纸牌,一字排开,纸牌有正反两面,开始的纸牌可能是一种乱的状态(有些朝正,有些朝反),现在你需要整理这些纸牌。但是 麻烦的是,每当你翻一张纸牌(由正翻到反,或者有反翻到正)时,他左右两张纸牌(最左边和最右边的纸牌,只会影响附近一张)也必须跟着翻动,现在给你一个 乱的状态,问你能否把他们整理好,使得每张纸牌都正面朝上,如果可以,最少需要多少次操作。
 

 

Input
有多个case,每个case输入一行01符号串(长度不超过20),1表示反面朝上,0表示正面朝上。
 

 

Output
对于每组case,如果可以翻,输出最少需要翻动的次数,否则输出NO。
 

 

Sample Input
01
011
 

 

Sample Output
NO
1
 
原题链接: http://acm.hdu.edu.cn/showproblem.php?pid=2209
 
 
思路:利用位运算搜索(枚举)即可
 
这是我ac代码 跑了593ms
 1 #include <iostream>
 2 #include <cstring>
 3 #include <queue>
 4 #include <cstdio>
 5 #define M (1<<21)
 6 using namespace std;
 7 int cnt[M];
 8 int BFS(int n,int m)
 9 {
10 
11     int t;
12     queue<int>pq;
13     cnt[n] = 1;
14     pq.push(n);
15     while(!pq.empty()){
16         int v = (3<<(m-2));
17         int vv = (7<<(m-3));
18         int num = pq.front();
19         pq.pop();
20         for(int i = 1; i <= m; i++){
21             if(i == 1){
22                 t = num^v;
23                 if(t == 0){
24                     cnt[t] = cnt[num];
25                     return cnt[t];
26                 }
27                 if(!cnt[t]){
28                     cnt[t] = cnt[num]+1;
29                     pq.push(t);
30                 }
31             }
32             else{
33                 t = num^vv;
34                 if(t == 0){
35                     cnt[t] = cnt[num];
36                     return cnt[t];
37                 }
38                 if(!cnt[t]){
39                     cnt[t] = cnt[num]+1;
40                     pq.push(t);
41                 }
42                 vv = vv>>1;
43             }
44 
45         }
46     }
47     return -1;
48 }
49 int main()
50 {
51     char str[25];
52     while(cin>>str){
53         memset(cnt,0,sizeof(cnt));
54         int number = 0,steps;
55         int len = strlen(str);
56         for(int i = 0; str[i]; i++){
57             number = number << 1;
58             if(str[i] == '1'){
59                 number = number | 1;
60             }
61         }
62         if(number == 0){
63             printf("0\n");
64             continue;
65         }
66         if(len == 1){
67             if(number == 1){
68                 printf("1\n");
69                 continue;
70             }
71         }
72         if(len == 2){
73             if(number == 3){
74                 printf("1\n");
75             }
76             else{
77                 printf("NO\n");
78             }
79             continue;
80         }
81         steps = BFS(number,len);
82         if(steps == -1){
83             printf("NO\n");
84         }
85         else{
86             printf("%d\n",steps);
87         }
88     }
89     return 0;
90 }
View Code

 

 
下面是网上0ms代码,orz。。。
 
 1 #include <stdio.h>
 2 #include <string.h>
 3 #include <algorithm>
 4 #include <math.h>
 5 #include <stdlib.h>
 6 using namespace std;
 7 const int inf = 1<<30;
 8 
 9 char str[30];
10 int a[30];
11 
12 int DFS(int i,int len,int m)
13 {
14     if(i == len)
15         return a[i-1]?inf:m;
16     if(a[i-1])
17     {
18         a[i-1] = !a[i-1];
19         a[i] = !a[i];
20         a[i+1] = !a[i+1];
21         m++;
22     }
23     DFS(i+1,len,m);
24 }
25 
26 int main()
27 {
28     int i,ans,len;
29     while(~scanf("%s",str))
30     {
31         len = strlen(str);
32         ans = inf;
33         for(i = 0; i<len; i++)
34             a[i] = str[i]-48;
35         a[0]=!a[0];
36         a[1]=!a[1];
37         ans = min(ans,DFS(1,len,1));//第一张牌翻转
38         for(i = 0; i<len; i++)
39             a[i] = str[i]-48;
40         ans = min(ans,DFS(1,len,0));//第一张牌没有手动翻转
41         if(ans == inf)
42             printf("NO\n");
43         else
44             printf("%d\n",ans);
45 
46     }
47 
48     return 0;
49 }
View Code

 

posted @ 2014-05-14 09:53  ZeroCode_1337  阅读(245)  评论(0编辑  收藏  举报