CARDS
Time Limit: 1000MS
Memory Limit: 10000K
Total Submissions: 1452
Accepted: 776
Description
Alice and Bob have a set of N cards labelled with numbers 1 ... N (so that no two cards have the same label) and a shuffle machine. We assume that N is an odd integer.
The shuffle machine accepts the set of cards arranged in an arbitrary order and performs the following operation of double shuffle : for all positions i, 1 <= i <= N, if the card at the position i is j and the card at the position j is k, then after the completion
of the operation of double shuffle, position i will hold the card k.
Alice and Bob play a game. Alice first writes down all the numbers from 1 to N in some random order: a1, a2, ..., aN. Then she arranges the cards so that the position ai holds the card numbered ai+1, for every 1 <= i <= N-1, while the position aN holds the
card numbered a1.
This way, cards are put in some order x1, x2, ..., xN, where xi is the card at the ith position.
Now she sequentially performs S double shuffles using the shuffle machine described above. After that, the cards are arranged in some final order p1, p2, ..., pN which Alice reveals to Bob, together with the number S. Bob‘s task is to guess the order x1, x2,
..., xN in which Alice originally put the cards just before giving them to the shuffle machine.
Input
The first line of the input contains two integers separated by a single blank character : the odd integer N, 1 <= N <= 1000, the number of cards, and the integer S, 1 <= S <= 1000, the number of double shuffle operations.
The following N lines describe the final order of cards after all the double shuffles have been performed such that for each i, 1 <= i <= N, the (i+1)st line of the input file contains pi (the card at the position i after all double shuffles).
Output
The output should contain N lines which describe the order of cards just before they were given to the shuffle machine.
For each i, 1 <= i <= N, the ith line of the output file should contain xi (the card at the position i before the double shuffles).
Sample Input
7 4
6
3
1
2
4
7
5
Sample Output
4
7
5
6
1
2
3
Source
CEOI 1998
题目大意:
第i个位置的牌是a[i],一次交换后第i个位置的牌变成a[a[i]]。序列所有位置经过一次交换为一次交换,
已知交换m次之后的序列,求原先序列
思路:想了一天,一直没明白什么意思,晚上才想明白。题目大意如上,不过需要注意的是 只能在
原有序列的基础上得到新的序列,而不能直接将原序列进行交换。
比如: 4 7 5 6 1 2 3
进行一次变换 6 3 1 2 4 7 5
而不能直接将原来第i个位置的牌改变,不能变成 6 3 1 2 6 3 5
意思就是说新的序列式在原有序列的基础上,在交换的过程中没有改变原有序列的值,从而得到一个
新的序列。
现在我们考虑变换次数和原先序列的关系
考虑 4 7 5 6 1 2 3
进行一次变换 6 3 1 2 4 7 5
进行两次变换 7 1 6 3 2 5 4
进行三次变换 4 7 5 6 1 2 3
原序列在第三次变换的时候出现了循环
考虑一般情况。因为原序列为1~N个不同的数,则序列能构成至少一个置换群,则经过多次变换后肯定
会出现循环,现在我们求出置换的循环节,已知新的序列,和进行交换的次数,则再进行res - s % res
次交换即可得到原序列。//res为循环节,s为给出的变换次数
#include <stdio.h> #include <string.h> int Array[1010],ArrayA[1010],ArrayB[1010]; void GetNext(int n) { for(int i = 1; i <= n; i++) ArrayB[i] = ArrayA[ArrayA[i]]; for(int i = 1; i <= n; i++) ArrayA[i] = ArrayB[i]; } bool IsSame(int n) { for(int i = 1; i <= n; i++) if(ArrayB[i]!=Array[i]) return false; return true; } int main() { int n,s; while(~scanf("%d%d",&n,&s)) { for(int i = 1; i <= n; i++) { scanf("%d",&Array[i]); ArrayA[i] = Array[i]; } int res; for(res = 1;;res++) { GetNext(n); if(IsSame(n)) break; } int m = res - s % res; int num = 0; while(num < m) { GetNext(n); num++; } for(int i = 1; i <= n; i++) printf("%d\n",ArrayB[i]); } return 0; }