Visitors hit counter dreamweaver

Roman Roulette(uva130)

    N个人排成一圈,按顺时针从1到N编号。从1开始顺时针数到第k个人,让其出圈,接着数到第k个人,让他站在出圈者的位置上。然后从出圈者的后继位置开始数,重复上述过程直到环中只剩1个人。当N=5,k=2时,出环者的顺序为:2,5,3,1;最后留下4。
   输入:N,k
   输出:I,使得从第I个人开始数,最后能留下第1人。
 
 分析:
   n当N=5,k=2时

   从1开始数,留下4;

   从2开始数,留下5;

   从3开始数,留下1;

   因此,输入5、2时,按照要求,应输出3

 

   n一般的情况:

   从1开始数,留下i;

   从2开始数,留下i+1;

   …

   从n-i+1开始数,留下i+ (n-i+1) -1 = n;

   从n-i+2开始数,留下i+ (n-i+2) -1 = 1;

   即对任意输入,设程序均从1开始数,则最后第i人留下,若希望第1人留下,则应从第n-i+2人开始数,因此输出:n-i+2。、

好,下面看代码吧。这分析也不是我想出来的,是人家课件上给出来的。代码也仅供参考哦~亲。加油加油!

#include <fstream>
#include <vector>
using namespace std;

int surviver(int n,int k);

int main(){
ifstream fin("Ein.txt");
ofstream fout("Eout.txt");
int n,k;
for(;fin>>n>>k && n;){
if(n==1)
fout<<1<<endl;
else{
fout<<n-surviver(n,k)+2<<endl; //surviver(n.k)为从第一个人开始计数,返回留下的那个人的编号i
//输出n-i+2
}
}
return 0;
}

int surviver(int n,int k){
vector<int>people;
int p=-1,p2,i; //数组从第0个开始计数,所以p取-1
for(i=0;i<n;i++){
people.push_back(i+1);
}
while(people.size()>1){
p=(p+k)%people.size();//找到第K个人
for(i=0,p2=p;i<k;i++){
p2=(p2+1)%people.size();//再从下一个开始计数,数到第N个人
if(p2==p) i--; //p已经被删除,所以不计数
}
people[p]=people[p2]; //用p2代替p
people.erase(people.begin()+p2); //删除节点
if(p>p2) p--; //这时环的个size减一了,如果p>p2,删除了p2后,p的值也要减一
}
return people[0];
}

 

 
posted @ 2011-12-05 00:31  Jason Damon  阅读(538)  评论(0编辑  收藏  举报