Time Limit: 3000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 1640 Accepted Submission(s): 348
1 10 3
10
设f(N,K)返回最后取出的编号那么f(n,k)进行第一次选后,剩下n-n/k个人,这剩下的人里最后被取出的编号为f(n-n/k,k)记为x那么它在前一次队列里的编号则是(x-1)/(k-1)+x所以f(n,k)=(x-1)/(k-1)+x 其中x=f(n-n/k,k)。
#include<stdio.h> int cal(int n,int k) { if(n==k)return k; int m=cal(n-n/k,k); return (m-1)/(k-1)+m; } int main() { int _case; int n,k; scanf("%d",&_case); while(_case--) { scanf("%d%d",&n,&k); printf("%d\n",cal(n,k)); } return 0; }
还有一个类似的题。
留下的士兵
输入包含几个测试数据。每个测试数据只占单独的一行,包含两个整数n和m(3 <= n <= 10^9, 2 <= m <= n)。当n=0 并且m=0的时候标志输入结束。
对于每组测试数据,输出两行。第一行包含一个整数X,表示最终留下的士兵的数量。第二行包含X个整数,表示最终留下的士兵的编号。你应该把他们按照升序输出。
10 3 8 3 0 0 |
1 9 2 3 6 |
#include<iostream> using namespace std; int main() { //freopen("in.txt","r",stdin); int i,j,n,m; while(scanf("%d%d",&n,&m) && n!=0){ int k=m; // while(n/(k)>=m) { k*=m; } cout<<n/k<<endl; int tmp=k; while(tmp<=n){ cout<<tmp<<" "; tmp+=k; } cout<<endl; } return 0; }
原文地址:http://blog.csdn.net/u012773338/article/details/38871451