p.s.自用
题目描述
小明正在使用一堆共 K 张纸牌与 N-1 个朋友玩取牌游戏。其中,N≤K≤100000,2≤N≤100,K 是 N 的倍数。纸牌中包含 M=K/N 张“good”牌和 K-M 张“bad”牌。小明负责发牌,他当然想自己获得所有“good”牌。
他的朋友怀疑他会欺骗,所以他们给出以下一些限制,以防小明耍诈:
1)游戏开始时,将最上面的牌发给小明右手边的人。
2)每发完一张牌,他必须将接下来的 P 张牌(1≤P≤10)一张一张地依次移到最后,放在牌堆的底部。
3)以逆时针方向,连续给每位玩家发牌。
小明迫切想赢,请你帮助他算出所有“good”牌放置的位置,以便他得到所有“good”牌。牌从上往下依次标注为 1,2,3,… k
输入
第 1 行,3 个用一个空格间隔的正整数 N、K 和 P。
输出
M 行,从顶部按升序依次输出“good”牌的位置。
样例输入 Copy
3 9 2
样例输出 Copy
3 7 8
答案
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#define MAX 100005
int q[MAX] = { 0 };
int rear, front;
int map[MAX] = { 0 };//good牌
void enQueue(int k)//入队
{
if ((rear + 1) % MAX == front)//判满
return;
else
{
q[rear] = k;
rear = (rear + 1) % MAX;//队尾指针加一取模
}
}
int deQueue()//出队
{
if (rear != front)//判空
{
int k = q[front];
front = (front + 1) % MAX;
return k;
}
}
void move(int p)
{
while (p--)
{
int k = deQueue();
enQueue(k);
}
}
void find(int n, int k, int p)
{
front = rear = 1;
for (int i = 1; i <= k; i++)
enQueue(i);
int good = k / n;
while (good--)
{
for (int i = 0; i < n - 1; i++)
{
deQueue();//发牌
move(p);//移牌
}
map[deQueue()] = 1;
move(p);
}
int count = 0;
for (int i = 1; i <= k; i++)
{
if (map[i])
{
printf("%d\n", i);
count++;
}
if (count == k / n)
break;
}
}
int main()
{
int n, k, p;
scanf("%d%d%d", &n, &k, &p);
find(n, k, p);
}