UVA1394 And Then There Was One

让我们来玩一个移除石子的游戏。

最初,n个石头按照顺时针的顺序围成一个圈,它们的编号是1,...,n.现在你将会得到两个数字k和m。之后,移除石子m,然后数k个石子移除一个,重复这个操作直到只剩下一个石子为止,求这个最后剩下的石子的编号。(与约瑟夫问题类似)

输入格式:

包含多组数据,以每行3个数的形式分别描述n,k,m. 最后以0 0 0结束.

输出格式:

对于每组数据,输出所求的最后石子编号。两组数据之间的输出需要更换一行。

暴力枚举行不通了。。。。。

 1 #include <stdio.h>
 2 #include <string.h>
 3 using namespace std;
 4 const int maxn=1e5+5;
 5 const int INF=1e9+5;
 6 int n,k,m,tot,t,a[maxn],f[maxn];
 7 template <class t>void red(t &x)
 8 {
 9     x=0;
10     int w=1;
11     char ch=getchar();
12     while(ch<'0'||ch>'9')
13     {
14         if(ch=='-')
15             w=-1;
16         ch=getchar();
17     }
18     while(ch>='0'&&ch<='9')
19     {
20         x=(x<<3)+(x<<1)+ch-'0';
21         ch=getchar();
22     }
23     x*=w;
24 }
25 void input()
26 {
27     freopen("input.txt","r",stdin);
28     //freopen("output.txt","w",stdout);
29 }
30 int main()
31 {
32     //input();
33     while(1)
34     {
35         red(n);
36         red(k);
37         red(m);
38         if(!n&&!k&&!m)
39             break;
40         tot=0;
41         f[1]=0;
42         for(int i=2;i<=n-1;++i)
43             f[i]=(f[i-1]+k)%i;
44         f[n]=(f[n-1]+m)%n+1;
45         printf("%d
",f[n]);
46     }
47     return 0;
48 }
View Code
原文地址:https://www.cnblogs.com/Achensy/p/10845548.html