HDU--1443 Joseph

来源:互联网 发布:redis java开发 编辑:程序博客网 时间:2024/05/17 23:11

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1443

曾经在一本算法书上看到这样一个关于Joseph问题的处理方法,数据结构不用链表,而是用数组。假设人数为n,步长为m,初始位置为pos(相当于指针,根据步长不停地移动)。数据结构使用bool类型,初始值为false,则下标i表示第i个孩子,而删除一个孩子k则使第k个元素的值为true。在根据步长查找下一个删除元素的时候,不计入值为true的元素。若pos超过n,,则将pos = 1。

可是,这个解法的弊端就是pos在移动的过程中,要判断每一个中间元素的bool值,这是很费时间的事情。尤其是在解决本问题时,求解步长是暴利穷举,而判断是否满足要求也费时间,整了半天也没有AC。在网上看人家的结题报告,思路就是挑出去一个坏人,总人数就减1不过没有看懂,唉....等以后再研究吧!

代码如下:

#include<iostream>#include<cstdio>#include<cstring>#include<iostream>#include<cmath>using namespace std;int res[16];//{0,2,7,5,30,169,441,1872,7632,1740,93313,459901,1358657,2504881};int fun(int n){int ans, flag, sum;if(res[n])return res[n];else{for(ans = n + 1; ; ++ans){flag = 0;sum = 2 * n;for(int j = ans; ; j += ans - 1) {if(j > sum)j = j % sum ? j % sum : sum; if(j <= n) break;elsesum--;//人数减1if(sum == n){flag = 1;break;}}if(flag){res[n] = ans;return res[n];}}}}int main(){int n;while(scanf("%d", &n) && n){printf("%d\n", fun(n));}return 0;}    
我的代码(没有AC):
#include<iostream>using namespace std;bool child[27];bool Joseph(int k,int m){int n = 2*k;memset(child,false,sizeof(child));int i = 0,count = n;int pos = 0;while(count>k){i = 0;while(i<m){if(pos+1>n)pos = 1;elsepos = pos+1;if(!child[pos]){i++;}}if(pos<=k)return false;child[pos] = true;count--;}return true;}int getAnswer(int k){     int i=k+1;     while (!Joseph(k,i)) i++;     return i;}int main(){int k;while(scanf("%d", &k) && k)      {          printf("%d\n", getAnswer(k));      }  return 0;}    





原创粉丝点击