思路:
报数的人是第几个,不是数组序号
// 0 1 2
// 1 2 0
// 0 2
// *
//
// 0 1 2 3 4 5 6
// 1 2 0 1 2 0 1
// 2 0 1 2 0
// 1 2 0
// 0 1
// *
方法一:
(超时)
#include <stdio.h>
int main(){
int n,k,sum,i;
while(scanf("%d",&n)&&n!=0){
int a[10000]={0}; //每一位为0表示未被淘汰
sum=0;i=0;k=0; //k为报的数字,sum为被淘汰多少人
while(1){
if(a[i]==0){ //如果没有被淘汰
k++; //就报数
if(k==3){ //如果报数到3
a[i]=1; //标记被淘汰
sum++;
if(sum==n) //当最后一个人被淘汰
break;
k=0;
}
}
i++; //下一个人报数
if(i>n-1) //i超过下表n-1de时候(第n个人),从0号人重新开始遍历
i=0;
}
printf("%d\n",i+1);
}
return 0;
}
方法二:
(超时)
#include <stdio.h>
int main(){
int n,k,flag,tag;
while(scanf("%d",&n)&&n!=0){
int a[n],tag;
k=1;flag=n;
for(int j=0;j<n;j++) {
a[j]=0;
}
while(flag!=1){ //当剩余人数不等于1人
for(int i=0;i<n;i++){
if(a[i]==0){ //当前人未被淘汰
if(k++%3==0){
a[i]=-1;
flag--;
}
}
}
}
for(tag=0;tag<n;tag++) //寻找未淘汰的人
if(a[tag]==0)
break;
printf("%d\n",tag+1);
}
return 0;
}
方法三:
//(旧-NUM)% sum = 新 —> 旧 =(新+NUM)% sum
具体的分析见->约瑟夫问题
#include <stdio.h>
#define NUM 3
int ysh(int sum,int num,int n){
if(n==1){
int t= (sum-1+num)%sum;
return t;
}
else{
int t= (ysh(sum-1,num,n-1)+num)%sum;
return t;
}
}
int main(){
int sum;
while(scanf("%d",&sum)&&sum!=0){
printf("%d\n",ysh(sum,NUM,sum)+1);
}
return 0;
}