您的位置:首页 > 理论基础 > 数据结构算法

数据结构 uva 133 - The Dole Queue

2013-01-13 14:28 148 查看
题目链接:

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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: