问题:
一个人玩起了接竹竿。
规则是,当一个人出的牌在上面的牌中有一样数字的,则他可以将这两个牌和两牌之间的牌拿走,然后再出一张扑克。
左手先出牌,所赢的牌是按照以前的顺序出的。
比如:左手剩了1,2两张牌,上一步赢了一次,是2,3,4,2 那么他的出牌顺序就是1,2,2,3,4,2。
当一个人手中没牌时,则另一个人胜利。
输入:
第一行一个数T,玩了T次
每次游戏开始是一个数n,只用了数字 <=n 的扑克,
后面有两行数字,每行有 2*n 个数,
第一行代表左手的扑克。
第二行代表右手的扑克。
1 <= T <= 10
1 <= n <= 13
输出:
对于每次游戏,输出游戏的结果,
(左右手累积出牌十万次不分输赢)
每次游戏输出占一行,左手赢输出1,
右手赢输出2,
平局输出0
分析:
左手,右手的 牌,可以分别 用一个队列来记录,方便从前删除,从后插入,以及判断是否为空。
打出去的牌可以用一个数组记录。
如果不懂 队列的 定义,可以看看。
代码:
#include<queue> #include<iostream> #include<string> #include<sstream> #include<algorithm> using namespace std; //左手先出牌 int main() { int T; cin>>T; //输入T while (T--) { int n,a; //用点数<=n的扑克牌 ,每个手有数量为2n的牌 int ping[20]; // 这个数组用来记录 左右手 已经出的牌 int lp,step; cin>>n; //输入n queue<int> left,right; //定义 左 右 两个队列。 for (int i=0;i<2*n;i++) // 左手的 2n 张牌 { cin>>a; left.push(a); // 从后面向队列中插入元素 } for (int i=0;i<2*n;i++) // 右手的 2n 张牌 { cin>>a; right.push(a); // 从后面向队列中插入元素 } step = 0; //记录出牌的次数 lp = 0; //lp是用来记录 已经出的牌的序号 int man=1; // man 是用来 帮助 判断是 左手,还是右手出牌的变量。。 int ans = 0 ; // 判断输赢的变量,平局为0 ,左赢为1, 右赢为2 while (step<100000) { if (man%2==1) { //先左手出牌 while (true) { step++; ping[lp++] = left.front(); //记录左手出的牌 left.pop(); //左手的牌 删去 最上面的一个 bool fafe = true; // for (int i=0;i<lp-1;i++) { if (ping[i]==ping[lp-1]) //ping[lp-1] 是刚刚出的牌。开始判断左手出的牌是否与前面的相同 { fafe = false; for (int j=i;j<lp;j++) //如果有相同的,就把中间这些牌都加到 left 队的后面。 left.push(ping[j]); lp = i; // 因为从 i 号牌拿走,所以下次发牌 的序号是第 i 个。 break; } } if (fafe) break; // 如果有相同的,就跳出循环 } if (left.empty()) // 如果 left 空 { ans = 2; // 右赢 break; } man^=1; // ^ 异或 运算,相同为 0,不同为 1.。。能走到这一步,说明没有相同的。man变成0 } // 那么下一次循环就从右手开始 else //右手 (同左手) { while (true) { step++; ping[lp++] = right.front(); right.pop(); bool fafe = true; for (int i=0;i<lp-1;i++) { if (ping[i]==ping[lp-1]){ fafe = false; for (int j=i;j<lp;j++) right.push(ping[j]); lp = i; break; } } if (fafe) break; } if (right.empty()) // 如果右手 空,左赢。 { ans = 1; break; } man^=1; //能走到这一步,说明没有相同的。man变成 1 .那么下次循环,就从左手开始 } } if (step>=100000) { ans = 0; // 10万次出牌没有胜负,为平局 cout<<ans<<endl; } else { cout<<ans<<endl; } } return 0; }