问题介绍
一个纸牌游戏,多名玩家数1~13,如果所数的数与最上面的牌的值相同,则传给下一个玩家,否则,将最上面的牌放至队尾。下一个玩家进行同样的操作,最后一名玩家遇到可以传递的牌,则丢弃而不是传给第一个玩家。胜利条件为最后一名玩家丢弃所有的牌。
输入:局数、玩家数、牌的顺序
输出:所有玩家最后丢弃(传递)的牌,或者unwinnable
问题剖析:
1、这道题用到的数据结构,queue(队列),即FIFO(先进先出),来模拟牌的状况。
2、这题的边界判断:什么时候为输----无线循环时,我采用的方法为,用一个steps数组记录下所有玩家,在丢弃下一张牌所需要花多少步,如果所花的步数,超过他自己手中牌乘以13的数值(即最差情况下,每一张手里牌都需要数13次才能数到这个数),这时,肯定是无法丢弃下一张牌,即输了。
下面是我的代码
#include<iostream>
#include<queue>
using namespace std;
int main(void) {
int j, t; // j for count, t for times.
cin >> t;
for (j = 0; j < t; ++j) {
// over is used to notice whether the loop is over.
// flag is used to notice whether the player is win.
int n, i, temp, over = 1, flag = 0, totalcard = 52;
// counter for each player's count number
// steps is to calculate how many step until we discard the next card
int counter[10], steps[10], answer[10];
queue<int> player[10];
// we create the queue array in this loop, so that after each loop it will automatically release the memory
// initialize
for (i = 0; i < 10; ++i) {
counter[i] = 1;
steps[i] = 0;
}
cin >> n;
// to store all 52 card number
for (i = 0; i < totalcard; ++i) {
cin >> temp;
player[0].push(temp);
}
while (over) {
for (i = 0; i < n; ++i) {
if (player[i].empty()) // if the queue is empty, we need not to do this loop
continue;
if (counter[i] == player[i].front()) { // is time to deal with the card
if (player[i].size() == 1) // if it is the last card of the queue
answer[i] = player[i].front(); // we need to store this card for answer
if (i != n - 1) // if it is not the last player
player[i + 1].push(counter[i]); // we pass the card to next one
else
--totalcard; // to count whether we discard all the card
player[i].pop(); // discard
steps[i] = 0; // count from begining
} else { // if our count not match the number of the front card
player[i].push(player[i].front());
player[i].pop();
// put the front card to the end
}
// add the counter and make sure it is not out of range
if (counter[i] >= 13)
counter[i] = 1;
else
++counter[i];
// if the steps that we need to discard one card is more than the steps that I can count all the card in the desk, it means we lose
if (steps[i] > (int)player[i].size() * 13) {
over = 0;
break;
}
++steps[i]; // add steps
}
if (totalcard == 0) { // we win
flag = 1;
over = 0;
}
}
cout << "Case " << j + 1 << ": ";
if (flag) {
for (i = 0; i < n - 1; ++i)
cout << answer[i] << ' ';
cout << answer[i] << endl;
}
else
cout << "unwinnable" << endl;
}
}