Time limit 1000 ms
Memory limit 131072 kB
Little A has became fascinated with the game Dota recently, but he is not a good player. In all the modes, the rdsp Mode is popular on online, in this mode, little A always loses games if he gets strange heroes, because, the heroes are distributed randomly.
Little A wants to win the game, so he cracks the code of the rdsp mode with his talent on programming. The following description is about the rdsp mode:
There are N heroes in the game, and they all have a unique number between 1 and N. At the beginning of game, all heroes will be sorted by the number in ascending order. So, all heroes form a sequence One.
These heroes will be operated by the following stages M times:
1.Get out the heroes in odd position of sequence One to form a new sequence Two;
2.Let the remaining heroes in even position to form a new sequence Three;
3.Add the sequence Two to the back of sequence Three to form a new sequence One.
After M times' operation, the X heroes in the front of new sequence One will be chosen to be Little A's heroes. The problem for you is to tell little A the numbers of his heroes.
Input
Each case contains three integers N (1<=N<1,000,000), M (1<=M<100,000,000), X(1<=X<=20).
Proceed to the end of file.
Output
Sample Input
5 1 2 5 2 2
Sample Output
2 4 4 3
Hint
In case two: N=5,M=2,X=2,the initial sequence One is 1,2,3,4,5.After the first operation, the sequence One is 2,4,1,3,5. After the second operation, the sequence One is 4,3,2,1,5.So,output 4 3.
题意是每次操作都会把偶数位置的数提出放到最前面来,然后操作次数很大,求操作后的序列前几位
先看一下我傻逼一样的超时代码
1 #include<cstdio> 2 #include<iostream> 3 #include<cmath> 4 #include<algorithm> 5 using namespace std; 6 7 struct node 8 { 9 int num; 10 int id; 11 }a[1000005]; 12 13 bool cmp(node b,node c) 14 { 15 return b.id<c.id; 16 } 17 18 int main() 19 { 20 int n,m,k; 21 int i,j; 22 while(~scanf("%d%d%d",&n,&m,&k)) 23 { 24 for(i=1;i<=n;i++) 25 { 26 a[i].num=i; 27 a[i].id=i; 28 } 29 //找循环结 30 bool flag=true; 31 for(i=1;i<=m;i++) 32 { 33 for(j=2;j<=n;j+=2) 34 a[j].id/=2; 35 for(j=1;j<=n;j+=2) 36 a[j].id=(a[j].id+1)/2+n/2; 37 sort(a+1,a+1+n,cmp); 38 flag=true; 39 for(j=1;j<=n;j++) 40 { 41 if(a[j].num!=j) 42 { 43 flag=false; 44 break; 45 } 46 } 47 if(flag) 48 break; 49 } 50 //取余 51 if(m!=i-1) 52 { 53 m%=i; 54 //最后操作 55 for(i=1;i<=n;i++) 56 { 57 a[i].num=i; 58 a[i].id=i; 59 } 60 for(i=1;i<=m;i++) 61 { 62 for(j=2;j<=n;j+=2) 63 a[j].id/=2; 64 for(j=1;j<=n;j+=2) 65 a[j].id=(a[j].id+1)/2+n/2; 66 sort(a+1,a+1+n,cmp); 67 } 68 printf("%d",a[1].num); 69 for(i=2;i<=k;i++) 70 printf(" %d",a[i].num); 71 printf(" "); 72 } 73 else 74 { 75 printf("%d",a[1].num); 76 for(i=2;i<=k;i++) 77 printf(" %d",a[i].num); 78 printf(" "); 79 } 80 } 81 return 0; 82 }
再看一下我们女队楼主的超强代码
1 #include <iostream> 2 #include<stdio.h> 3 using namespace std; 4 #define maxn 1000000 5 int n; 6 int ci; 7 int a[maxn+1000]; 8 int k; 9 int T(int x) 10 { 11 int c=1; 12 int cnt=0; 13 do{ 14 if(c*2<=n) 15 { 16 c*=2; 17 } 18 else 19 { 20 c=(c-n/2)*2-1; 21 } 22 cnt++; 23 }while(c!=1); 24 return cnt; 25 } 26 int main() 27 { 28 while(~scanf("%d%d%d",&n,&ci,&k)) 29 { 30 ci%=T(n); 31 for(int i=1;i<=n;i++)a[i]=i; 32 for(int i=1;i<=k;i++) 33 { 34 35 for(int j=1;j<=ci;j++) 36 { 37 if(a[i]*2<=n) 38 { 39 a[i]=2*a[i]; 40 } 41 else{ 42 a[i]=(a[i]-n/2)*2-1; 43 } 44 } 45 if(i==1)cout<<a[i]; 46 else cout<<" "<<a[i]; 47 } 48 cout<<endl; 49 50 } 51 return 0; 52 }
所以我是不是个傻逼。。。
是。。