您的位置:首页 > 产品设计 > UI/UE

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

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