1589: 反转地球,颠覆世界
时间限制: 1 Sec 内存限制: 128 MB 提交: 14 解决: 10 [提交][状态][讨论版]
题目描述
北欧巨人沉睡了几万年后苏醒过来了,他们想做的第一件事就是让整个世界回到属于他们的那个“神话”时代。万能的上帝知道此事后和巨人们产生如下对话:
上帝:你们知道怎么返回“神话”时代吗?
巨人:...(巨人不知道)
上帝:反转地球便可颠覆世界呀!
巨人: ...(此时巨人顿时醒悟)
上帝:我是公平的,如果你们能在我的游戏中胜出,我便助你们返回“神话”时代。
上帝的游戏是这样的:
游戏基于N张纸牌,上面分别标着1、2、3、4.....N-1、N 这N个数字。游戏有一个操作叫“反转”:把当前排列纸牌的第一张纸牌放到最后。例如如果当前有3张纸牌,而且排列是:1、2、3,那么经过一次“反转”操作后,这3张纸牌的排列便变成:2、3、1;如果再进行一次“反转”操作,则变成:3、1、2;依次类推。
上帝会指定一个正整数M,为了以示公平,巨人可以任意选择N张纸牌的一种排列,例如N为3时共有6种排列(1 2 3, 1 3 2, 2 1 3, 2 3 1, 3 1 2, 3 2 1)可以选择。然后上帝会对这个序列依次进行下面操作:
a.把第一张纸牌从当前纸牌的序列清除掉;
b.对当前序列做M次“反转”操作;
c.如果当前序列还有纸牌,返回操作a,否则开始操作d;
d.如果上帝清除掉纸牌的顺序是1、2、3、....、N-1、N,那么巨人就在游戏中胜出,否则巨人失败。
例如:N=3,M=1时,如果玩家给出的纸牌序列是1、3、2;
在进行操作a后,会把第一张纸牌清除掉,此时的纸牌序列变成3、2;然后进行操作b后,纸牌的序列变成2、3;再进行操作c时发现当前序列还有纸牌,需要回到操作a;第二次操作a后,纸牌的序列变成3,依次类推,直到N张纸牌都被取消,便进行操作d,产生游戏结果。
巨人们苦想了很久都不知道怎么从游戏中获胜,但他们听说你是纸牌高手,所以想请你给出这N张纸牌的一个排列,以帮助他们从游戏中胜出,而且他们觉得你如果能完成,说明你很聪明,就让你做他们的领导人。
输入
输入包含多组测试数据。
每组测试数据占一行,每行包含两个整数N(1<N<500)、M(1<M<500)。
N和M同时为0的时候表示输入数据结束。
输出
每组测试数据都应该输出一行,包含N个数字,数字间用一个英文空格隔开,最后一个数字后面没有空格。N和M同时为0时不用输出。
样例输入
3 1
3 2
3 3
5 2
13 1
0 0
样例输出
1 3 2
1 2 3
1 3 2
1 5 3 2 4
1 12 2 8 3 11 4 9 5 13 6 10 7
提示
1 #include <cstdio>
2 #include <vector>
3 #include <cmath>
4 #include <queue>
5 #include <cstring>
6 #include <iostream>
7 #include <algorithm>
8 using namespace std;
9 #define INF 0x7fffffff
10 #define mod 1000000007
11 #define ll long long
12 #define maxn 100005
13 #define pi acos(-1.0)
14 int n, m;
15 int a[maxn],b[maxn];
16 int main(){
17 while (scanf("%d%d", &n, &m) && (n + m)){
18 memset(a, 0, sizeof a);
19 int k = 1, j = 0; a[0] = 1; b[0] = 1;
20 for (int i = 0; k<n; i++){
21 if (i == n)i = 0;
22 if (a[i] == 0)j++;
23 if (j == m+1)a[i] = 1, b[i] = ++k, j = 0;
24 }
25 for (int i = 0; i < n; i++)printf(i==n-1?"%d\n":"%d ", b[i]);
26 }
27 return 0;
28 }
View Code