ccf报数游戏java_ccf 201712 02 (游戏)

鄙人不才,此中鄙陋甚多,望海涵!!!

这里我们来详细讲解一下圆桌问题的相关题目

第一道一定是hdu的4841了,罪恶的源头

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

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

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

输入

2 3

2 4

输出

GBBG

BGGB

C++代码

#include

#include

using namespace std;

vector res;

int main()

{

int n,m;

while(cin>>n>>m)

{

res.clear();//用res来模拟圆桌

for(int i=0;i<2*n;i++) res.push_back(i);//先将这2n个人放入res中;

int p=0;

for(int i=0;i

{

p=(p+m-1)%res.size();//每次先定位该死的坏人的位置,注意res下标从0开始,而且

//涉及到取余问题,记得减一

res.erase(res.begin()+p);//将坏人抹杀

}

for(int i=0,cnt=0;i<2*n;i++)

{

if(i%50==0 && i) puts("");//每50行输出一个换行

if(cnt

{//别忘了cnt

printf("G");

cnt++;

}

else printf("B");

}

cout<

}

return 0;

}

圆桌问题的简单应用

题目

“Eeny meeny miny moe” is a well-known nursery rhyme inEnglish, used (among other things) by kids to “randomly”select members of a team. It exists in many variations, oneof which goes like this:

Eeny, meeny, miny, moe,

Catch a tiger by the toe.

If he hollers, let him go,

Eeny, meeny, miny, moe.

Similar verses exist in most languages, such as “Ulle dulle dof” in Finnish, “Akka bakka bonka rakka” in Norwegian, and “Ole dole doff” in Swedish.

Two teams are to be selected for a game and the rhyme is used to select one kid for a team at a time, alternating between the two teams, until all kids have been selected. The kids are standing in a circle. In each selection round we start counting the kids in clockwise order around the circle, skipping one kid for every word in the rhyme, until the last word. The kid matching the last word is chosen for the current team and then the next round starts. In all rounds but the first, the counting starts at the next remaining kid (in clockwise order) after the one that was selected in the previous round.

Given such a rhyme, and a group of kids, can you tell which kids will be in which team?

Illustration of the first three rounds of Sample Input 1. In rounds 1 and 3, Alvar and Rakel get selected for the first team, and in round 2, Lisa is selected for the second team. In round 4 (not shown), only Kalle remains and is selected for the second team.

Input

The first line of input contains the rhyme, consisting of a list of words separated by spaces. The second line of input contains an integer n (1 ≤ n ≤ 100), the number of kids. Then follow the names of the kids, one per line. The kids are given in clockwise order and the first kid listed is the one at which counting starts in the first round.

All words and names consist only of upper and lower case letters ‘A’-‘Z’ and ‘a’-‘z’. No input line is empty or longer than 100 characters (excluding the newline character at the end of the line).

Output

Output the two teams, starting with the one whose first member is chosen first. For each team, output the number of kids in the team, followed by the names of the kids in the team, in the same order as they were chosen for the team.

样例1输入

eeny meeny miny

4

Kalle

Lisa

Alvar Rakel

样例1输出

2

Alvar

Rakel

2

Lisa

Kalle

样例2输入

Every Other

3

a

b

c

样例2输出

2

b

c

1

a

C++code

#include

#include

using namespace std;

vector a;

vector b;

vector sum;

string s;

int main()

{

int cnt=0,n=0;

while(cin>>s)

{

if(s[0]>='a' && s[0]<='z' || s[0]>='A' && s[0]<='Z') cnt++;

else

{

for(int i=0;i

break;

}

}

for(int i=0;i

{

string item;

cin>>item;

sum.push_back(item);

}

int m=1;

while(sum.size())

{

int pos=(pos+cnt-1)%sum.size();

if(m&1)

{

a.push_back(sum[pos]);

sum.erase(sum.begin()+pos);

}

else

{

b.push_back(sum[pos]);

sum.erase(sum.begin()+pos);

}

m++;

}

cout<< a.size() <

for(auto x:a) cout<< x <

cout<< b.size() <

for(auto x:b) cout<< x <

return 0;

}

总算是回到了游戏这题,这题其实就是属于圆桌问题的变种,关键就在于把报数的过程转化为每隔几个人就会被淘汰的问题,这就相当于n个人只有一个是好人,从第一个人开始每隔几个人就会抹杀一个坏人,最终剩下一个好人胜出

关键:处理这个隔几个人的问题

题目请到ccf官网自提

C++ Code

#include

#include

using namespace std;

vector res;//用res来模拟圆桌

int main()

{

int n,k;

cin>>n>>k;

for(int i=1;i<=n;i++) res.push_back(i);

for(int i=0,cnt=1,m=0;i

{

if(cnt%k==0 || cnt%10==k)

{

int p=(p+m)%res.size();

res.erase(res.begin()+p);

m=0,i++;//将m归0,并且淘汰人数加1

}

else m++;//这里m就是距离上一次淘汰所间隔人数

cnt++;//cnt表示所报的数

}

cout<< res[0] <

return 0;

}

持续更新中。。。。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值