题目为:
圆桌上围坐着 2n 个人。其中 n 个人是好人,另外 n 个人是坏人。如果从第一个人开始数数,数到第 m 个人,则立即处死该人;然后从被处死的人之后开始数数,再将数到的第 m 个人处死,依此方法不断处死围坐在圆桌上的人。试问预先应如何安排这些好人与坏人的座位,能使得在处死 n 个人之后,圆桌上围坐的剩余的 n 个人全是好人。
Input
输入正整数 n 和 m,(1 ≤ n ≤ 5 × 105, 1 ≤ m ≤ 109)
Output
输出 2n 个大写字母,'G'表示好人,'B' 表示坏人,不允许出现空白字符。
Examples
Input:2 3; Output:GBBG
Input:2 4;Output:BGGB
解法:
我们使用模拟。
首先根据题目,我们怎么判断是死是活呢?我们可以先设置2n个数组大小,全部设置为1,1代表存活,当计数到被m整除的时候,就将此时数组对应下标的值设置为0,0代表处死。
然后我们继续考虑怎么进行这个游戏?最简单的方式自然是循环,从第1个人数到最后一个人,遇到存活的玩家就计数,否则跳过该玩家,再回到第一个人重新继续数数,这里我们需要考虑怎么回到开头,一个常见的做法是取模,我这里则到尾部后直接回到开头重新循环也是可以的。
继续,我们要考虑什么时候循环终止?题目上指明了处死的人只有n人,所以我们需要一个处死人数dead的统计,在每次处死的时候都进行加1,当处死人数大于等于n时,不再进行轮回游戏。此时要注意在内部循环可能最后一轮还在继续进行,所以要在内部也设置条件判断终止游戏。
最后,我们要考虑怎么输出?自然,遍历数组,当遇到1输出G,遇到0输出B。
下方是完整代码
#include <iostream>
using namespace std;
void judge(int *a,int n,int m){
int i,count=0,dead=0;
while(dead<n){
for (i=1;i<=2*n;i++){
if (a[i]==0){
continue;
}
count++;
if (count%m==0){
a[i]=0;
count=0;
dead++;
if (dead>=n){
return;
}
}
}
}
}
int main(){
int m,n,*a;
cin>>n>>m;
a=new int [2*n+1];
memset(a, 1, sizeof(int) * (2*n+1)); // 将数组a的前2*n个元素设置为1
judge(a,n,m);
for (int i=1;i<=2*n;i++){
if (a[i]==0)
{
cout<<'B';
}
else{
cout<<'G';
}
}
delete [] a;
}
3209

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



