hdu4841 圆桌问题

来源:互联网 发布:html下拉框显示数据库 编辑:程序博客网 时间:2024/04/30 01:18

圆桌问题

Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 65535/32768 K (Java/Others)
Total Submission(s): 18    Accepted Submission(s): 3


Problem Description
圆桌上围坐着2n个人。其中n个人是好人,另外n个人是坏人。如果从第一个人开始数数,数到第m个人,则立即处死该人;然后从被处死的人之后开始数数,再将数到的第m个人处死……依此方法不断处死围坐在圆桌上的人。试问预先应如何安排这些好人与坏人的座位,能使得在处死n个人之后,圆桌上围坐的剩余的n个人全是好人。
 

Input
多组数据,每组数据输入:好人和坏人的人数n(<=32767)、步长m(<=32767);
 

Output
对于每一组数据,输出2n个大写字母,‘G’表示好人,‘B’表示坏人,50个字母为一行,不允许出现空白字符。相邻数据间留有一空行。
 

Sample Input
2 32 4
 

Sample Output
GBBGBGGB

n*2个人的约瑟夫环,找出前n个被踢出去的人,二分答案位置,剩下的就是区间求和了。

/* *===================== *File Name:  *Author: qqspeed *Date: 2014年 07月 01日 星期二 13:36:21 CST *===================== */#include <stdio.h>#include <string.h>#include <iostream>#include <string>#include <queue>#include <stack>#include <map>#include <math.h>#include <vector>#include <stdlib.h>#include <algorithm>using namespace std;typedef long long ll;#define rep(i,s,t) for(int i=s;i<t;i++)#define red(i,s,t) for(int i=s-1;i>=t;i--)#define ree(i,now) for(int i=head[now];i!=-1;i=edge[i].next)#define clr(a,v) memset(a,v,sizeof a)#define L t<<1#define R t<<1|1#define max(a,b) (a<b?b:a)#define min(a,b) (a<b?a:b)#define SQR(a) ((a)*(a))#define lowbit(x) (x&(-x))inline int input(){int ret=0;bool isN=0;char c=getchar();while(c<'0' || c>'9'){if(c=='-') isN=1;c=getchar();}while(c>='0' && c<='9'){ret=ret*10+c-'0';c=getchar();}return isN?-ret:ret;}inline void output(int x){        if(x<0){            putchar('-');x=-x;        }        int len=0,data[11];        while(x){            data[len++]=x%10;x/=10;        }        if(!len)    data[len++]=0;        while(len--)           putchar(data[len]+48);        putchar('\n');  }  const int MAXN=33000;int n,m,N;bool vis[MAXN<<1],tag=0;bool ok[MAXN<<1];int c[MAXN<<1];inline void add(int x,int v){while(x<=N) c[x]+=v,x+=lowbit(x);}inline int Sum(int x){int ans=0;while(x) ans+=c[x],x-=lowbit(x);return ans;}inline int bs(int s,int t,int v,int pre){while(s<=t){int mid=(s+t)>>1;int sum=Sum(mid)-pre;if(sum==v && !ok[mid]) return mid;else if(sum<v) s=mid+1;else t=mid-1;}}int main(){while(~scanf("%d%d",&n,&m)){N=n*2;clr(c,0);clr(ok,0);rep(i,1,N+1) add(i,1);int a=1;clr(vis,0);rep(i,0,n){int s1=Sum(N);int s2=Sum(a-1);int mm=m%s1;if(mm==0) mm=s1;if(s1-s2>=mm){a=bs(a,N,mm,s2);vis[a]=1;add(a,-1);ok[a]=1;a++;if(a==N+1) a=1;}else{int res=mm-s1+s2;a=bs(1,N,res,0);vis[a]=1;ok[a]=1;add(a,-1);a++;if(a==N+1) a=1;}}rep(i,1,N+1){putchar(!vis[i]?'G':'B');if(i%50==0) puts("");}puts("");puts("");}return 0;}


0 0