soj.1003 hit or miss

问题介绍

一个纸牌游戏,多名玩家数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;
  }
}


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值