题目链接:
http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=69
题目意思:
一共有n个编号分别为1-n的人,站成一圈,两位公务员分别从1和n号人开始分别沿逆时针和顺时针方向分别每隔k和m个人,挑选获取申请书的人名单顺序,如果两位公务员同时选到相同的人则只用输出一次。优先输出第一个公务员的挑选名单,因为是同时的挑选,计数的时候如果恰好被另一个公务员选中,也要计数。
解题思路:
用双向链表模拟选人的过程,分别用count指针(逆时针的),clock指针(顺时针的),如果挑选出来了,就从链表中删除掉,用挑选出来的人数作为结束的控制条件。具体的注意细节看程序。
代码:
#include<iostream>
#include<cmath>
#include<cstdio>
#include<cstdlib>
#include<string>
#include<cstring>
#include<algorithm>
#include<vector>
#include<map>
#define eps 1e-6
#define INF (1<<20)
#define PI acos(-1.0)
using namespace std;
struct Node
{
int data;
struct Node * next,* pre;
};
int n;
struct Node * Count, *Clock; //注意不能用clock,可能是同系统的冲突
void build() //建立双向循环链表
{
struct Node *p;
p=Count=Clock=(struct Node *)malloc(sizeof(struct Node)); //注意只有1个元素的时候,clock也有值,也是个循环链表
Count->data=1;
Count->next=Count->pre=NULL;
for(int i=2;i<=n;i++)
{
Clock=(struct Node *)malloc(sizeof(struct Node));
Clock->data=i;
Clock->next=NULL;
Clock->pre=p; //双向循环链表
p->next=Clock;
p=Clock;
}
Clock->next=Count;
Count->pre=Clock;
return ;
}
void solve(int k,int m)
{
int flag=0,num=0;
while(1) //用输出的个数控制结束,比较简单,如果用单个节点控制的话,不统一
{
for(int i=2;i<=k;i++)
Count=Count->next;
for(int i=2;i<=m;i++)
Clock=Clock->pre;
if(Count->data==Clock->data) //两个指针同时指向一个地方,只用输出一个
{
if(num==n-1) //判断结束
{
printf("%3d\n",Count->data);
flag=1;
}
else
{
printf("%3d,",Count->data); //注意是占三个字符
num++;
}
Count=Count->next;
Clock=Clock->pre;
free(Clock->next);
if(flag==1)
return ;
Clock->next=Count; //删除该节点
Count->pre=Clock;
}
else
{
if(num==n-2)
{
printf("%3d%3d\n",Count->data,Clock->data);
flag=1;
}
else
{
printf("%3d%3d,",Count->data,Clock->data);
num+=2;
}
(Count->next)->pre=Count->pre; //删除count节点
(Count->pre)->next=Count->next;
struct Node * temp=Count;
Count=Count->next;
free(temp);
if(flag==1)
return ;
(Clock->next)->pre=Clock->pre; //删除clock节点
(Clock->pre)->next=Clock->next;
temp=Clock;
Clock=Clock->pre;
if(Count==temp) //注意当前一个指针移到了当前要删除指针的位置,
Count=temp->next;
free(temp);
}
}
return ;
}
int main()
{
int k,m;
while(scanf("%d%d%d",&n,&k,&m)&&n+k+m)
{
build();
solve(k,m);
}
return 0;
}