一.扑克游戏
【问题描述】
桌上有一叠牌,从第一张牌(即位于顶面的牌)开始从上往下依次编号为1~n;当至少还剩两张牌时进行以下操作:把第一张牌扔掉,然后把新的第一张放到整叠牌的最后。当剩下最后一张时也扔掉。
输入n,输出每次扔掉的牌。
【输入】
输入文件名为kard.in。
输入共一行,一个正整数n,表示牌的张数。
【输出】
输出文件名为kard.out。
输出共一行,依次是扔掉牌的编号。
【输入输出样例】
kard.in |
kard.out |
7 |
1 3 5 7 4 2 6 |
【数据范围】
100%的数据:n<=54.
我们一起来看看没学过队列,只学到函数的学生是如何完成的:
2017级
1.lhc版、zh版
其实是队列的思路:
用了变量i 和n分别表示队首指针和队尾指针。模拟了出队和入队。当队列中有大于等于2个元素时一直模拟。只有一个元素时,直接输出。
#include<iostream> #include<cstdio> using namespace std; int n; int a[110]; int main() { freopen("kard.in","r",stdin); freopen("kard.out","w",stdout); cin>>n; for(int i=1;i<=n;i++) a[i]=i; for(int i=1;i<=n;i++) { if(n-i>=1) { cout<<a[i]<<" "; i++; n++; a[n]=a[i]; } if(i==n) { cout<<a[i]; break; } } return 0; }
2.wzr (用一个数组进行模拟,x记录当前需要处理那一对数,x+n是当前后移的数应该存放的位置。)
#include<iostream> #include<cstdio> #include<algorithm> #include<cstring> #include<cmath> using namespace std; int n,t; int a[1000100]; int main(){ freopen("kard.in","r",stdin); freopen("kard.out","w",stdout); cin>>n; t=n; for(int i=1;i<=n;i++) a[i]=i; int x=1; while(t>2){ cout<<a[x]<<" "; a[x+t]=a[x+1]; t--; x+=2; } if(t==2) cout<<a[x]<<" "<<a[x+1]; return 0; }
3.ljx版
找规律:n个数,每次都是扔掉奇数位置的数,偶数位置的数后移。
每个数只有处于奇数位置时才会被输出,共有n个数,则最后一个数所在的位置为2*n-1,也就是说,在模拟时n个数需要占用2n-1个元素空间。
1 #include<iostream> 2 #include<cstdio> 3 using namespace std; 4 int main(){ 5 freopen("kard.in","r",stdin); 6 freopen("kard.out","w",stdout); 7 int b[1001],n; 8 cin>>n; 9 for(int i=1;i<=n;i++) 10 b[i]=i; 11 for(int i=1;i<=2*n;i++){ 12 if(i%2==1) 13 cout<<b[i]<<" "; 14 else b[n+i/2]=b[i]; 15 16 } 17 return 0; 18 }
4.dlt版(思路同3)
#include<iostream> #include<cstdio> using namespace std; int a[200]; int main(){ freopen("kard.in","r",stdin); freopen("kard.out","w",stdout); int n,k,d; cin>>n; k=n+1; for(int i=1;i<=n;i++){ a[i]=i; //cout<<a[i]; } for(int i=1;i<=200;i+=2){ if(a[i]!=0) cout<<a[i]<<" "; a[k++]=a[i+1]; } return 0; }