题目连接:http://acm.pku.edu.cn/JudgeOnline/problem?id=1012
版本一:
本身是个错误版本,错误地方在下面标出
#include <iostream>
using namespace std;
int main()
{
// freopen("in.txt","r",stdin);
int k,count;
int res,next,num;
while(cin >> k && k)
{
count = 2*k - 1;
for(res = next = k + 1,num = 1;num <= k;)
{
next += res - 1;
if(next > count)
next -= count;//有时减去一个count不行的
if(next >= 1 && next <= k)
{
count = 2*k - 1;
++res;
num = 1;
next = res;
}
else
{
++num;
--count;
}
}
cout << res << endl;
}
return 0;
}
版本二:通过循环模拟士兵出队情况,结果超时!
#include <iostream>
using namespace std;
#define MAX 14
int main()
{
freopen("in.txt","r",stdin);
bool in[MAX],ok;
int k,size;
int i,b,c,cc,n;
while(cin >> k && k)
{
size = 2*k;
ok = false;
c = k + 1;
while(!ok)
{
b = n = 0;
memset(in,true,sizeof(in));
while(n < k)
{
for(i = b;!in[i];i = (i+1)%size);
cc = 1;
while(cc < c)
{
i = (i+1)%size;
if(in[i])
++cc;
}
if(i >= 0 && i < k)
{
++c;
break;
}
else
{
in[i] = false;
b = i;
++n;
}
}
if(n == k)
ok = true;
}
cout << c << endl;
}
return 0;
}
版本三:因为题目并没有要求出队信息,所以省去对出队信息的维护。通过计算的方法求取每个出队士兵的下标,但是还是超时!
#include <iostream>
using namespace std;
#define MAX 14
int main()
{
freopen("in.txt","r",stdin);
bool ok;
int k;
int c,size;
int b,n,next;
while(cin >> k && k)
{
c = k + 1;
ok = false;
while(!ok)
{
size = 2*k;
b = n = 0;
while(n < k)
{
next = (b + c - 1) % size;
if(next >= 0 && next < k)
{
++c;
break;
}
else
{
b = next;
++n;
--size;
}
}
if(n == k)
ok = true;
}
cout << c << endl;
}
return 0;
}
版本四:通过一次建表,以后查询的方法通过!看来空间换时间和建表加速的意识还有待提高啊!
#include <iostream>
using namespace std;
#define MAX 14
bool Ok(int k,int c)
{
int size;
int b,n,next;
size = 2*k;
n = b = 0;
while(n < k)
{
next = (b + c - 1) % size;
if(next >= 0 && next < k)
return false;
--size;
++n;
b = next;
}
return true;
}
int main()
{
freopen("in.txt","r",stdin);
int i,j,res[MAX];
for(i = 1;i <= 13;++i)
{
j = i + 1;
while(!Ok(i,j))
++j;
res[i] = j;
}
while(cin >> i && i)
cout << res[i] << endl;
return 0;
}
Joseph问题的解法一:直接用循环模拟士兵的出队情况比较耗时
#include <iostream>
using namespace std;
#define MAX 15
int main()
{
// freopen("in.txt","r",stdin);
bool in[MAX];
int i,b,c,cc,n,size;
while(cin >> size >> c)
{
b = n = 0;
memset(in,true,sizeof(in));
while(n < size)
{
for(i = b;!in[i];i = (i+1)%size);
cc = 1;
while(cc < c)
{
i = (i+1) % size;
if(in[i])
++cc;
}
in[i] = false;
cout << i << ' ';
b = i;
++n;
}
cout << endl;
}
return 0;
}
Joseph问题的解法二:通过移动元素修改队伍中的剩余人数,计算下次出对的人的下标
#include <iostream>
using namespace std;
#define MAX 14
int main()
{
int pep[MAX],size;
int i,c,b,next;
while(cin >> size >> c)
{
for(i = 0;i < size;++i)
pep[i] = i;
b = 0;
while(size)
{
next = (b + c-1) % size;
cout << pep[next] << ' ';
for(i = next + 1;i < size;++i)
pep[i-1] = pep[i];
b = next;
--size;
}
cout << endl;
}
return 0;
}