POJ-3629 模拟

时间:2021-11-01 15:43:56
A - Card Stacking

Time Limit:1000MS     Memory Limit:65536KB     64bit IO Format:%I64d & %I64u

Submit Status

Description

Bessie is playing a card game with her N-1 (2 ≤ N ≤ 100) cow friends using a deck with K (N ≤ K ≤ 100,000; K is a multiple of N) cards. The deck contains M = K/N "good" cards and K-M "bad" cards. Bessie is the dealer and, naturally, wants to deal herself all of the "good" cards. She loves winning.

Her friends suspect that she will cheat, though, so they devise a dealing system in an attempt to prevent Bessie from cheating. They tell her to deal as follows:

1. Start by dealing the card on the top of the deck to the cow to her right

2. Every time she deals a card, she must place the next P (1 ≤ P ≤ 10) cards on the bottom of the deck; and

3. Continue dealing in this manner to each player sequentially in a counterclockwise manner

Bessie, desperate to win, asks you to help her figure out where she should put the "good" cards so that she gets all of them. Notationally, the top card is card #1, next card is #2, and so on.

Input

* Line 1: Three space-separated integers: NK, and P

Output

* Lines 1..M: Positions from top in ascending order in which Bessie should place "good" cards, such that when dealt, Bessie will obtain all good cards.

Sample Input

3 9 2

Sample Output

3
7
8
 一个模拟题,我想了一下就决定用队列来模拟发牌过程,事实证明也很顺利,只是不知为何,OJ会说我runtime error,我把数组什么的都尽量开大了,还是没办法,难道队列还能爆?这根据题目的数据,不可能啊。。后来我搜了一下博客,也有跟我思路完全一样的人,但是人家用JAVA写的,就过了。我就很奇怪,不过我自认为我的程序应该是没有问题了。
过了两天,因为正好又碰到一个runtime error的题目,这次我找到我代码的BUG是发现有个地方会引起无限循环从而使数组爆掉,改好后就AC了,我再想起这个题目,于是今晚回过头来改一下,发现只要在队列中,判断依据 if(sum>=k/n) break;,也就是说,只要找到了题目要求的k/n个最好牌,就直接退出队列模拟。。。然后再提交,就AC了。。于是乎,我终于找到出问题的地方了,就是在模拟里面,每次while(!q.empty())循环里面出现了超过2次q.pop(),也就是说模拟到最后的牌,其实q队列已经空了,但是还是会继续访问下去,这样就是问题所在,果不其然,我拿之前错的代码,改了一个新的地方,在循环体里面还判断一下队列是否为空。。果不其然就A掉了
之前还在骂这个题目,为这个一个小BUG弄的时间比写代码的时间还长。。还是不够老练啊。。本来 if(sum>=k/n) break;这种代码明显可以优化时间(AC了几次发现这句话确实为我节省了几十ms) 我在第一次写的时候就应该写上的。。还至于到了最后不仅没有任何优化,还因为这样的小细节弄出自己半天都想不出来的bug。谨以为记。
顺便吐槽一下,POJ上没说是多组数据的样子啊。。怎么要用到while(scanf()!=EOF)?
代码自认为用队列用得挺好。
#include <iostream>
#include <cstdio>
#include <queue>
#include <algorithm>
using namespace std;
int ans[];
int main()
{
int n,k,p;
while (scanf("%d%d%d",&n,&k,&p)!=EOF){
queue<int> q;
while (!q.empty())
q.pop();
for (int i=;i<=k;i++)
q.push(i);
int cur=;
int sum=;
while (!q.empty()) //模拟发牌过程,发到直至队列里没有牌
{
if (cur%n==){
ans[sum]=q.front();
sum++;
}
if (sum>=k/n) break;
q.pop();
cur++;
for (int j=;j<p;j++)
{
int a=q.front();
q.pop();
q.push(a);
}
}
sort(ans,ans+sum);
for (int w=;w<sum;w++)
printf("%d\n",ans[w]);
}
return ;
}