题目链接:
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;
}
本文介绍了一道UVA在线评测题目,该题要求使用双向链表模拟两个公务员逆时针和顺时针挑选申请书的过程。文章详细解释了解题思路,并提供了完整的C++代码实现。
531

被折叠的 条评论
为什么被折叠?



