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

提示

反转list java 反转地球_#include

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