[SCOI2005]扫雷
考虑如果第一个格子是否是雷确定了,那么a[1]的合法性就确定了(a[]代表输入的一串数)。这样对于a[2],唯一不确定的格子就是b[3](b[i]代表i这个格子是否有雷),而b[3]又可以根据a[2]而定,所以说只要第一个格子确定,整个序列就确定了。因为一个格子只有有雷和没有雷的情况,所以答案只有0, 1, 2。然后分类讨论一下,然后判断是否合法就行了。
1 #include<cstdio> 2 #include<iostream> 3 #include<cmath> 4 #include<algorithm> 5 #include<cstring> 6 #include<cstdlib> 7 #include<cctype> 8 #include<vector> 9 #include<stack> 10 #include<queue> 11 using namespace std; 12 #define enter printf("\n") 13 #define space printf(" ") 14 #define Mem(a) memset(a, 0, sizeof(a)) 15 typedef long long ll; 16 typedef double db; 17 const int INF = 0x3f3f3f3f; 18 const int eps = 1e-8; 19 const int maxn = 1e4 + 5; 20 inline ll read() 21 { 22 ll ans = 0; 23 char ch = getchar(), last = ' '; 24 while(!isdigit(ch)) {last = ch; ch = getchar();} 25 while(isdigit(ch)) {ans = ans * 10 + ch - '0'; ch = getchar();} 26 if(last == '-') ans = -ans; 27 return ans; 28 } 29 inline void write(ll x) 30 { 31 if(x < 0) x = -x, putchar('-'); 32 if(x >= 10) write(x / 10); 33 putchar(x % 10 + '0'); 34 } 35 36 37 int n, a[maxn]; 38 39 bool b[maxn]; 40 bool judge() 41 { 42 for(int i = 1; i < n; ++i) //判断有点多…… 43 { 44 if(!a[i]) 45 { 46 if(b[i - 1] || b[i]) return 0; 47 } 48 else if(a[i] == 1) 49 { 50 if(b[i - 1] + b[i] > 1) return 0; 51 if(b[i - 1] + b[i] == 0) b[i + 1] = 1; 52 } 53 else if(a[i] == 2) 54 { 55 if(b[i - 1] + b[i] > 2) return 0; 56 if(b[i - 1] + b[i] < 1) return 0; 57 if(b[i - 1] + b[i] == 1) b[i + 1] = 1; 58 } 59 else 60 { 61 if(b[i - 1] + b[i] < 2) return 0; 62 if(b[i - 1] + b[i] == 2 && i < n) b[i + 1] = 1; 63 } 64 } 65 if(b[n - 1] + b[n] < a[n]) return 0; //最后一个格子要特判,因为到头了 66 return 1; 67 } 68 69 int ans = 0; 70 71 int main() 72 { 73 n = read(); 74 for(int i = 1; i <= n; ++i) a[i] = read(); 75 Mem(b); b[1] = 1; 76 if(judge()) ans++; 77 Mem(b); b[1] = 0; 78 if(judge()) ans++; 79 write(ans); enter; 80 return 0; 81 }