标签:
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 286 Accepted Submission(s): 105
历史学家弗拉维·约瑟夫曾讲述过这样的故事:在公元前67年的罗马犹太战争中,罗马攻下了他掌权的城市。随后,他与另外40个反抗战士一起逃到了一个山洞中而被困在里面。罗马人发现了他的下落并劝他投降,但他的战士们拒绝投降。于是他提议互相杀死对方,一个接一个,顺序由大家决定。有一种传统的方式,即为了公平起见所有人都站成一个环,从某一点开始,循环计数,每隔两个活着的人就杀掉一个。最后只有约瑟夫幸存了下来,投降了罗马。问题来了,约瑟夫如何知道一开始站第31位才会幸存到最后呢?是不是趁着洞穴黑暗大家没注意,悄悄地用41个石子演练过了?还是他用数学方法计算出了这个位置?
在仔细读过这个故事由来后,你逐渐克服了恐惧心理,不再害怕将来这种事会发生到你的头上。但为了应对这种类似的情况,你准备为你的手机写一个程序,以便快速的计算这个过程并确保你能站到最后幸存的位置上。
类似于约瑟夫所述的问题,你的程序需要处理如下改编过的问题。最初n(n > 0)个人面朝内围成一个环,并依次按顺时针编号1到n。你的编号为1,第一个轮到的人编号为i,同样顺时针方向开始计数,直到第k(k > 0)个人把他杀掉。然后再从下一个还活着的人开始向后数到第k个人,由这个人来把刚才杀掉的人埋葬,并站到被杀的人的位置上。然后再从他左面第一个还活着的人开始计数,杀掉第k个人,以此类推,直到只有一个人还活着。
比方说,n = 5,k = 2,i = 1,被杀的顺序应为:2、5、3和1。4幸存。
类似于经典的约瑟夫环问题,这类问题都是可以用数学推导求出通式的。但这道题目的过程要远比约瑟夫环问题复杂得多,分析通式比较困难,且由于数据量很小(少于100人),可直接按模拟类型的题目对待求解。
模拟的实现使用动态数组是非常方便的,过程也很简单。数组初始存储每一个人的编号,从第0个元素(1号)开始计数,每次杀死一个人前先不要将这个人的编号删除,而是先找出要来埋他的人,将他们的编号互换,然后将埋他的人原来所在的位置删掉即可。最后计算出的是从1号开始计数,最后能幸存的人编号p,那么从你前面第p个人开始你就是安全的(你站在第1位),即n – p。这个换算的原理是显而易见的。
这个是找你前面第p个人开始你就是安全的;
由这个人来把刚才杀掉的人埋葬,并站到被杀的人的位置上
题解:
1 #include<iostream> 2 #include<algorithm> 3 #include<cstdio> 4 #include<cstring> 5 #include<cmath> 6 #include<vector> 7 #include<map> 8 #include<stack> 9 #include<queue> 10 #define mem(x,y) memset(x,y,sizeof(x)) 11 /*#define L tree[root].l 12 #define R tree[root].r 13 #define S tree[root].sum 14 #define NOW tree[root<<1].sum+tree[root<<1|1].sum 15 #define lson root<<1,l,mid 16 #define rson root<<1|1,mid+1,r*/ 17 using namespace std; 18 const int INF=0x3f3f3f3f; 19 vector<int>vec; 20 int main(){ 21 int n,k,flot=0; 22 while(scanf("%d%d",&n,&k),n|k){ 23 vec.clear(); 24 for(int i=1;i<=n;i++) 25 vec.push_back(i); 26 int pos=0,kisp=(k-1)%vec.size(); 27 while(vec.size()>1){ 28 pos=(kisp-1+k)%(vec.size()-1); 29 pos=(pos+(pos>=kisp))%vec.size(); 30 vec[kisp]=vec[pos]; 31 vec.erase(vec.begin()+pos); 32 kisp=(kisp+k-(pos<kisp))%vec.size(); 33 } 34 printf("%d\n",(n - vec.front() + 1) % n + 1); 35 //printf("Case %d: %d\n",++flot,*vec.begin()); 36 } 37 return 0; 38 }
标签:
原文地址:http://www.cnblogs.com/handsomecui/p/4906589.html