读书人

(急){帮人者人恒帮之}改进约瑟夫(报数

发布时间: 2012-02-17 17:50:41 作者: rapoo

(急){帮人者人恒帮之}改进约瑟夫(报数方法采用顺时针报数和逆时针报数交替进行)
改进约瑟夫问题的描述是:编号为1,2,…,n的n个人按顺时针方向围坐一圈, 每人有一个密码Ki(整数),留作其出圈后应报到Ki后出圈。报数方法采用顺时针报数和逆时针报数交替进行,初始密码可任意确定。求最后剩下的人的编号





我只是初级者,帮过新手!!!
希望被帮~~~
大大们救我~~
实在想不出来了~~~
马上课程设计结束了~~~

[解决办法]

C/C++ code
 
]/**
@ Content:杀人游戏之递归算法LAV版
杀人游戏
N个人坐成一圈玩杀人游戏,按顺时针编号 1 2 3 4 ... ...
从1号开始顺时针开始数到第m号就杀掉第一个人,被杀掉的人要退出游戏。
如果数到了编号的末尾,就逆时针indicator继续数,如果又数到了编号的开头,就恢复顺时针继续。
重复,直至杀掉所有人,当剩下最后一个人时,游戏结束,聪明的你能告诉我活到最后的幸存者最初的编号是多少吗?

输入数据:N、M

输出数据:幸存者的编号

@ Author :Eastsun
@ Version:1.0
*/
#define MAX_N 1000
#define MAX_LEN 8
int solve(int n,int m,int k){
int killer[MAX_N+1];
int index,temp,result;
m--; k--;
killer[n] =k;
for(index =n-1;index>=3;index--)
if((temp=m%(index+1))==killer[index+1])killer[index] =index -1;
else killer[index] =(killer[index+1]+index-temp)%(index+1);
if(killer[3]==m%3) result =(killer[3]+2)%3;
else result =3-killer[3]-m%3;
for(index =4;index <=n;index++)
if(killer[index]==m%index) result =(result+m+2)%index;
else result =(result+m+1)%index;
return result+1;
}
long getNum(int x,int y,int max){//取得一个不大于max的正数
char numKey[11];
char buf[MAX_LEN+2],key;
long num,n,k;
strcpy(numKey,"0bnmghjtyu");
buf[MAX_LEN+1] =0;
n =num =0;
while(1){
memset(buf+n,' ',MAX_LEN+1-n);
buf[n] ='_';
TextOut(x,y,buf,0x41);
key =getchar();
if(key==0x0d){
TextOut(x+n*6,y," ",0x41);
return num;
}
if(key==0x1b){
TextOut(x+n*6,y," ",0x41);
return -1;
}
if(key==23&&n>0){
n--;
num =num/10;
}
else{
for(k=0;k <10&&numKey[k]!=key;k++);
if(k>=10||n>=MAX_LEN||num*10+k>max) continue;
buf[n++]=k+'0';
num =num*10+k;
}
}
}
void main(){
int n,m,k;
char text[20];
while(1){
ClearScreen();
Refresh();
TextOut(2,1,"Input N(2 <N <1001):",0x41);
if((n=getNum(110,1,1000)) <3) break;
TextOut(2,15,"Input M(0 <M):",0x41);
if((m=getNum(80,15,0x7fff)) <=0) break;
TextOut(2,29,"Input K(0 <K <=N):",0x41);
if((k=getNum(98,29,n)) <=0) break;
sprintf(text,"Position :%d",solve(n,m,k));
TextOut(8,43,text,0x41);
if(getchar()==0x1b) break;
}
}

读书人网 >C++

热点推荐