这道题是有两种方法做的,第一种是用链表的方式模拟整个过程,(用数组的话剔除猴子会不方便),由于不熟练+实验楼的垃圾电脑,回到宿舍后边查资料边打的。要注意到链表迭代器删除的时候(erase,remove)是会销毁掉迭代器的,同时返回一个指向下一个位置的迭代器,这时候需要注意此时不++。由于是手动++,++应放在整个循环的最末端。
#include <iostream>
#include <list>
using namespace std;
class Monkey
{
public:
Monkey(int n = 0, int m = 0)
{
num = n;
call = m;
}
int num;
int call;
};
int main()
{
int t;
cin >> t;
while (t--)
{
int n, m;
int count = 1;
cin >> n >> m;
list <Monkey> monkey;
list<Monkey>::iterator iter;
for (int i = 0; i <= n - 1; i++)
{
monkey.push_back(Monkey(i + 1));
}
for (iter=monkey.begin();;)
{
(*iter).call = count++;
if (count == m + 1)
{
iter = monkey.erase(iter); //del and iter++
count = 1;
if (monkey.size() == 1)
{
cout << monkey.back().num << endl;
break;
}
}
else
{
iter++;
}
if (iter == monkey.end()) //return
{
iter = monkey.begin();
}
}
}
system("pause");
}
另外一种方法就是通过数学手段找到规律,每次被剔除的猴子的序号可以由n和m得出,只需不断循环即可。
// Problem#: 19254
// Submission#: 4823436
// The source code is licensed under Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License
// URI: http://creativecommons.org/licenses/by-nc-sa/3.0/
// All Copyright reserved by Informatic Lab of Sun Yat-sen University
#include <iostream>
using namespace std;
int main()
{
int t;
cin >> t;
int n,m;
for(int i=0;i<t;i++)
{
cin >> n >> m;
int a[1000];
for(int j=0;j<n;j++)
{
a[j]=j+1;
}
int k=0;
while(n>1)
{
k=(k+m-1)%n;
for(int p=k;p<n;p++)
{
a[p]=a[p+1];
}
n--;
}
cout << a[0] << endl;
}
}