这题我用的静态链表,感觉还是比较绕的,,有一个小trick,比如当k走到a位置,m走到b位置,而a的下一个位置就是b,这就必须特殊处理了
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <iostream>
#include <algorithm>
#include <map>
#include <vector>
#include <set>
using namespace std;
#define N 100
#define dbag printf("%d\n", n);
int L[100], R[100];
void link(int a, int b)
{
R[a] = b;
L[b] = a;
}
int main()
{
int n, k, m;
while(scanf("%d%d%d", &n, &k, &m))
{
if(n==0)break;
for(int i = 2; i <= n; i++)
L[i] = i-1;
L[1] = n;
for(int i = 1; i <= n-1; i++)
R[i] = i+1;
R[n] = 1;
k = (k-1)%n; m = (m-1)%n;
int cnt = n;
int posk = 1, posm = n;
while(cnt>=1)
{
int tk = 0;
while(tk<k)
{
posk = R[posk];
tk++;
}
int tm = 0;
while(tm<m)
{
posm = L[posm];
tm++;
}
if(posk!=posm)
{
cnt-=2;
printf("%3d", posk);
if(cnt==0)
{printf("%3d\n", posm);break;}
else
printf("%3d,", posm);
int prek = posk; posk=R[posk];
int prem = posm; posm=L[posm];
if(posk==prem&&cnt>=2) //特殊情况,当posk走到下一位置恰好是m当前的位置
{
posk=R[posk];
posm=L[posm];
link(L[prek], R[prem]);
}
else
{
link(L[prek], R[prek]);
link(L[prem], R[prem]);
}
}
else
{
cnt -= 1;
if(cnt==0)
{printf("%3d\n", posk);break;}
else
printf("%3d,", posk);
int prek = posk; posk=R[posk];
int prem = posm; posm=L[posm];
link(L[prek], R[prek]);
}
}
}
return 0;
}
后面又想了下,,上面的做法太操蛋,,换了个写法
//这种约瑟夫环问题,直接用bool数组模拟,不用考虑删除数,数之间的链接问题
//因为用bool标记已访问,在逻辑上顺序是没变的
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <iostream>
#include <algorithm>
#include <map>
#include <vector>
#include <set>
using namespace std;
#define N 200
int main()
{
int n, k, m;
while(scanf("%d%d%d", &n, &k, &m))
{
if(n==0)break;
bool vis[N];
memset(vis, false, sizeof(vis));
int cnt = n;
k = (k-1)%n+1; m = (m-1)%n+1;
int posk = -1, posm = n;
while(cnt>0)
{
int tk = 0, tm = 0;
while(tk<k)
{
posk++; posk%=n;
if(!vis[posk])
tk++;
}
while(tm<m)
{
posm--;if(posm<0)posm = n-1;
if(!vis[posm])
tm++;
}
if(posm==posk)
{
cnt-=1;
if(cnt==0)
printf("%3d\n", posk+1);
else
printf("%3d,", posk+1);
vis[posm]=true;
}
else
{
cnt-=2;
if(cnt == 0)
printf("%3d%3d\n", posk+1, posm+1);
else
printf("%3d%3d,", posk+1, posm+1);
vis[posk] = true; vis[posm] = true;
}
}
}
return 0;
}