Codeforces Round #304 C(Div. 2)(模拟)
http://codeforces.com/problemset/problem/546/C
题意:
总共有n张牌,1手中有k1张分别为:x1, x2, x3, ..xk1,2手中有k2张,分别为:y1, y2, ...yk2;(n<=10&&k1+k2==n,所有牌的数字都不同);
依次比较x1, y1的大小,若x1>y1,依次将x1, y1加入x牌最底下;反之则将y1,x1依次加入y牌最底下;直至有方的牌输完为止;输出总共游戏的步数和赢方;
如果两方都不能赢,则输出-1;
思路:直接用栈模拟,关键的地方是判断两方都不能赢的情况,判断方法有两种:
其一是设一个足够大的数,超过这个步数还没有分出输赢情况的话则可以认定
两方都不能赢,因为n<=10,如果能分出输赢的话则500步以内一定会出结果的!
另一种方法是判断当前状态之前是否出现过,若出现过,则其一定不能分出输赢!会死循环!
至于如何判断是否出现过,可以将每个状态都存入一个string数组中,再将当当前状态与之对比,若出现过,则平局;
代码分别如下:
方法1:
1 #include<bits/stdc++.h> 2 #define MAXN 10000 3 #define MAX 1000000000 4 #define eps 1e-6 5 #define ll long long 6 using namespace std; 7 8 int main(void) 9 { 10 queue<int> stk1, stk2; 11 string str1[MAXN], str2[MAXN]; 12 int n, a, b, ans=0; 13 cin >> n; 14 cin >> a; 15 for(int i=0; i<a; i++) 16 { 17 int x; 18 cin >> x; 19 stk1.push(x); 20 } 21 cin >> b; 22 for(int i=0; i<b; i++) 23 { 24 int x; 25 cin >> x; 26 stk2.push(x); 27 } 28 int cnt=0, flag; 29 while(1) 30 { 31 int x=stk1.front(), y=stk2.front(); 32 if(x>y) //****如果x>y,将y, x依次从队尾加入stk1队列,并将stk2,stk1队首元素y, x抛掉; 33 { 34 stk1.push(y); 35 stk1.push(x); 36 stk1.pop(); 37 stk2.pop(); 38 } 39 else //****如果x<y,将x, y依次从队尾加入stk2队列,并将stk2, stk1队首元素y, x抛掉; 40 { 41 stk2.push(x); 42 stk2.push(y); 43 stk2.pop(); 44 stk1.pop(); 45 } 46 cnt++; 47 if(stk1.empty()) //****队列stk1为空,即2赢了 48 { 49 cout << cnt << " " << "2" << endl; 50 return 0; 51 } 52 if(stk2.empty()) //****队列stk2为空,即1赢了 53 { 54 cout << cnt << " " << "1" << endl; 55 return 0; 56 } 57 if(cnt>500) break; //****如果步数大于500还没分输赢,即可判平局 58 } 59 cout << "-1" << endl; 60 return 0; 61 }
方法2:
1 #include<bits/stdc++.h> 2 #define MAXN 10000 3 #define MAX 1000000000 4 #define eps 1e-6 5 #define ll long long 6 using namespace std; 7 8 int main(void) 9 { 10 queue<int> stk1, stk2; 11 string str1[MAXN], str2[MAXN]; 12 int n, a, b, ans=0; 13 cin >> n; 14 cin >> a; 15 for(int i=0; i<a; i++) 16 { 17 int x; 18 cin >> x; 19 stk1.push(x); 20 } 21 cin >> b; 22 for(int i=0; i<b; i++) 23 { 24 int x; 25 cin >> x; 26 stk2.push(x); 27 } 28 int cnt=0, flag; 29 while(1) 30 { 31 int low1[MAXN], low2[MAXN], k1=0, k2=0; 32 while(!stk1.empty()) //**将stk1存入string数组中 33 { 34 low1[k1++]=stk1.front(); 35 stk1.pop(); 36 } 37 for(int i=0; i<k1; i++) 38 { 39 stk1.push(low1[i]); 40 } 41 for(int i=0; i<k1; i++) 42 { 43 str1[cnt]+=to_string(low1[i]); 44 } 45 while(!stk2.empty()) //****将stk2存入string数组中 46 { 47 low2[k2++]=stk2.front(); 48 stk2.pop(); 49 } 50 for(int i=0; i<k2; i++) 51 { 52 stk2.push(low2[i]); 53 } 54 for(int i=0; i<k2; i++) 55 { 56 str2[cnt]+=to_string(low2[i]); 57 } 58 for(int i=0; i<cnt; i++) //***判断当前状态是否出现过,若出现过,则平局 59 { 60 if(str1[i]==str1[cnt]&&str2[i]==str2[cnt]) 61 { 62 cout << "-1" << endl; 63 return 0; 64 } 65 } 66 int x=stk1.front(), y=stk2.front(); 67 if(x>y) //****如果x>y,将y, x依次从队尾加入stk1队列,并将stk2,stk1队首元素y, x抛掉; 68 { 69 stk1.push(y); 70 stk1.push(x); 71 stk1.pop(); 72 stk2.pop(); 73 } 74 else //****如果x<y,将x, y依次从队尾加入stk2队列,并将stk2, stk1队首元素y, x抛掉; 75 { 76 stk2.push(x); 77 stk2.push(y); 78 stk2.pop(); 79 stk1.pop(); 80 } 81 cnt++; 82 if(stk1.empty()) //****队列stk1为空,即2赢了 83 { 84 flag=2; 85 break; 86 } 87 if(stk2.empty()) //****队列stk2为空,即1赢了 88 { 89 flag=1; 90 break; 91 } 92 } 93 cout << cnt << " " << flag << endl; 94 return 0; 95 }
我就是我,颜色不一样的烟火 --- geloutingyu