挑兵挑将
算法部分
#include<bits/stdc++.h>
//布尔型数组中,true为1,false为0
//数组A,起始位置为K,当前位置为p,每一步步长为d,其中d为1(正循环)或-1(负循环),循环体周期长度为T
//当前位置为p,则下一个位置的坐标为(p-k+d+T)%T+k
using namespace std;
int n,k,m;
bool a[26];//该点是否被访问过
//p:当前位置 d:+1表示逆时针,-1表示逆时针 T:循环体周期长度,这里为n k:起始位置,这里为1
//c表示每次走几步,也就是需要进行几次位置变动
int select(int p,int d,int c)
{
while(c--)//进行c次循环,此处c==k,或者c==m
{
do{
p=(p-1+d+n)%n+1;
}while(a[p]==0);
// do while 该循环会先执行一次代码块,然后对条件表达式进行判断,如果条件为真,就会重复执行循环体,否则退出循环。
}//解释:若满足该位置已经被查找过,继续往下找
return p;
}
int main( )
{
while(cin>>n>>k>>m && !(n==0&&k==0&&m==0))
{
for(int i=1;i<=n;i++)
{
a[i]=true;
}
int remain = n;//淘汰后还剩下多少人,初始时为n
int pa=n,pb=1;//当前位置都要往前走一步
while(remain)
{
pa=select(pa,1,k);//A每次逆时针方向走k步
pb=select(pb,-1,m);//每次都顺时针方向走m步
if(pa==pb)//判断需要淘汰的位置是否为同一个
{
remain--;
printf("%3d",pa);
}
else
{
remain=remain-2;
printf("%3d%3d",pa,pb);
}
a[pa]=a[pb]=0;//每次淘汰后都要进行标记
if(remain)
printf(",");
}
printf("\n");
}
return 0;
}