紫书章四例题3——UVA 133 TheDole Queue

来源:互联网 发布:对称轴画图软件手机 编辑:程序博客网 时间:2024/06/10 00:38

题意:有1-n人逆时针围成一个圈,然后A从1开始逆时针开始数,到k停止,然后将那个人去掉,B同时从n顺时针开始数,到m个人的时候停止,将该人去掉。这为一轮。
然后这道题的目的主要还是简化代码。然后还有学到了一些小点
1.人数的话,总数都可以用left表示,然后减减,最后判断是否为0即可。不用再和以前一样,用vis数组,然后再排序了。
2.bg=(bg+d+n-1)%n+1;

代码

#include <iostream>#include <cstdio>#include <cstring>#include <algorithm>#include <cmath>using namespace std;int n;int vis[30];int qd(int d,int bg,int k){    int g=0;    for(bg=bg;;bg=(bg+d+n-1)%n+1)    {        if(!vis[bg]) {g++;}        if(g==k) break;    }    return bg;}int main(){    //freopen("D:\\input.txt","r",stdin);    int k,m;    while(scanf("%d %d %d",&n,&k,&m)!=EOF&&n+m+k)    {        memset(vis,0,sizeof(vis));        int left=n;        int p=1,q=n;        while(left)        {            p=qd(1,p,k);            q=qd(-1,q,m);            printf("%3d",p),left--;            if(p!=q) printf("%3d",q),left--;            vis[p]=vis[q]=1;            if(left) printf(","); else printf("\n");        }    }    return 0;}

然后书上在编写函数的时候用了dowhile,但是中间的一个点要注意,p开始的时候为n,q为1.因为在函数中会多走一步。所以之前要减去

#include <iostream>#include <cstdio>#include <cstring>#include <algorithm>#include <cmath>using namespace std;int n;int vis[30];int qd(int d,int bg,int k){    while(k--){    do{bg=(bg+d+n-1)%n+1;} while(vis[bg]==1);}//当vis[bg]==1的时候执行do。直到走到下一个有人的位置,也就是vis为0        return bg;}int main(){    //freopen("D:\\input.txt","r",stdin);    int k,m;    while(scanf("%d %d %d",&n,&k,&m)!=EOF&&n+m+k)    {        memset(vis,0,sizeof(vis));        int left=n;        int p=n,q=1;//        while(left)        {            p=qd(1,p,k);            q=qd(-1,q,m);            printf("%3d",p),left--;            if(p!=q) printf("%3d",q),left--;            vis[p]=vis[q]=1;            if(left) printf(","); else printf("\n");        }    }    return 0;}
0 0
原创粉丝点击