201712-2游戏
//此代码运行超时,仅供参考,下一个是正确代码
#include <stdio.h>
int main(){
int num=1,n,k,l=0,a[1000]; //l为每轮淘汰小朋友人数
scanf("%d%d",&n,&k);
for(int i=0;i<n;i++)
a[i]=i+1; //初始化数组,给所有小朋友编号
while(n!=1){ //一直循环直到剩余一人
for(int index=0;index<n;index++){ //index为数组下标
if(num%k==0||num%10==k){
l++; //符合淘汰条件,淘汰人数加一
}
else //如果轮到他未被淘汰
a[index-l]=a[index]; //则将他前移l位
num++;
}
n=n-l; //本轮淘汰完剩余人数
l=0; //将淘汰人数清零
}
printf("%d",a[0]); //最后数组里只剩下一个元素a[0],即获胜小朋友编号
return 0;
}
这是第一次写的,写完还挺高兴。
运行超时90分,题目要求在1s内解决。我寻思着难道是因为时间复杂度整成n^2了,这可咋改啊?苦思冥想又请教了一下大神:整成队列就完事了。
#include<algorithm>
#include<cstdio>
#include<queue>
using namespace std;
int main(){
int num=1,n,k,w; //w为最后获胜小朋友编号
queue<int> c; //c为children队列
scanf("%d%d",&n,&k);
for(int i=1;i<=n;i++)
c.push(i); //初始化队列,给所有小朋友编号
while(!c.empty()){ //一直循环直到最后一个小朋友也出队
w=c.front(); //得到当前小朋友编号
c.pop(); //将这个小朋友移出队列
if(num%k==0||num%10==k); //若符合淘汰条件,啥都不做
else c.push(w); //本轮不被淘汰,则把他加到队尾
num++;
}
printf("%d",w); //最后记录的w即获胜小朋友编号
return 0;
}
如此看来,队列竟然比双重循环快一点,学到了。
欢迎交流指导。