poj1781

规律题

题意:n个人站成一圈,从第一个人开始,每隔一个杀一个,问哪个人最后被杀。

分析:虽然题目中认为这些人是站成一圈一杀到底,但是我们可以认为这些人是站成一排,每次从第二个活人开始,或者从第一个活人开始,从左到右每隔一个杀一个,直到只剩一个活人。如果我们每次给活人从1开始编号,那么每次从第二个杀,则每个活人的编号会变为(i - 1)/2+1,从第一个则变为i/2。最后剩一个编号为1的人。我们要做的就是记录每次从第几个开始杀,然后逆推,将编号为1的最后一个活人的编号按照刚才的规则,并根据每次从第一还是第二开始杀,逆推出其原编号。

 

View Code
#include <iostream>
#include
<cstdlib>
#include
<cstring>
#include
<cstdio>
usingnamespace std;

#define maxn 100

int n;
int f[maxn];
int ans;

void work()
{
int t =0;
int x = n;
bool next =true;
while (x >1)
{
f[t
++] = next;
int y = x;
x
-= x /2+ ((next ^1) & (x &1));
next
= ((next ^1) & (y &1)) | (next & ((y &1) ^1));
}
ans
=1;
for (int i = t -1; i >=0; i--)
ans
= ans *2- f[i];
printf(
"%d\n", ans);
}

int main()
{
//freopen("t.txt", "r", stdin);
char st[10];
while (scanf("%s", st), strcmp(st, "00e0"))
{
n
= (st[0] -'0') *10+ st[1] -'0';
for (int i ='0'; i < st[3]; i++)
n
*=10;
work();
}
return0;
}

你可能感兴趣的:(poj)