2022年江西省程序设计大赛G题:A Game of Taking Numbers题解

题目描述:

rqdmap and his little girlfriend are playing a game. There are n positive integers. These two people take turns, taking the numbers. In order to show his Gentlemanliness, rqdmap asked his little girlfriend to take the numbers fifirst.

Every time rqdmap’s little girlfriend can choose any number from the remaining numbers to take away (recorded as x), rqdmap needs to choose a number from the remaining numbers (recorded as y), and at least one of the following two conditions is met:

1. |x − y| ≤ 3, that is, the difffference between the absolute values of x and y cannot exceed 3.

2. x ≡ y (mod 3), that is, x and y modulo 3 are congruent.

If rqdmap cannot select a qualifified number from the remaining numbers, rqdmap’s little girlfriend wins, otherwise rqdmap wins. rqdmap and his little girlfriend are smart enough. Now that you have obtained these numbers before the game starts, please judge who will win the game in the end.


中文翻译:

Rqdmap和他的小女友在玩游戏。有n个正整数。这两个人轮流数。为了显示他的绅士风度,rqdmap让他的小女朋友先拿号码。
每次rqdmap的小女友可以从剩余的数字中选择任意一个数字带走(记录为x), rqdmap需要从剩余的数字中选择一个数字(记录为y),并且至少满足以下两个条件中的一个:
1. |x−y|≤3,即x与y的绝对值之差不能超过3。
2. X≡y(取3模),即X与y取3模相等。
如果rqdmap不能从剩余的号码中选择一个合格的号码,rqdmap的小女友获胜,否则rqdmap获胜。Rqdmap和他的小女友够聪明的。既然你在比赛开始前已经得到了这些数字,请判断谁将最终赢得比赛。


题目思路:

1、首先n如果为奇数,那男生必输;

2、如果n为偶数,那在考虑{首先把数分为三堆,A(%3==0),B(%3==1),C(%3==2)}

2.1.如果三堆个数分别为偶数,则男生赢;男生的思路来说:我取是让堆里始终为偶数;

2.2如果三堆里面个数是(奇,奇,偶);

2.2.1,从奇数堆里拿一个,从偶数里拿一个;如果取成功了,男生就可以赢得胜利

2.2.2,如果上面没取成功,则从两个奇数堆里取两个数;如果取成功了,男生就可以胜利

2.2.3,如果以上都没成功,则女生赢了

题目代码:(代码是参照:先相信,再想信)

#include<bits/stdc++.h>
#define endl '\n'
#define IOS ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
#define int long long
using namespace std;
int a[1000009];
void solve()
{
	int n;
	cin>>n;
	vector<int>p[3];
	map<int,int>mp;
	int a0=0,a1=0,a2=0;//分了三堆,计数
	for(int i=1; i<=n; i++)
	{
		cin>>a[i];
		mp[a[i]]++;
		p[a[i]%3].push_back(a[i]);
		if(a[i]%3==0) a0++;
		else if(a[i]%3==1) a1++;
		else a2++;
	}
	int flag=0;
	if(a0%2==0&&a1%2==0&&a2%2==0) 
	{
		cout <<"rqd"<<endl;
		return ;
	}
	if(n%2==1)
	{
		cout <<"His little girlfriend"<<endl;
		return ;
	}
	if(n%2==0)
	{
		int x=0;
		while(p[x].size()%2==1) x++;
		int l=-1,r=-1;
		
		for(int i=0; i<p[x].size(); i++)
		{
			if(mp.count(p[x][i]+1)||mp.count(p[x][i]-2)) 
			{
				l=i;
				break;
			}
		}
		for(int i=0; i<p[x].size(); i++)
		{
			if(i!=l&&(mp.count(p[x][i]+2)||mp.count(p[x][i]-1))) 
			{
				r=i;
				break;
			}
		}//这两循环是判断了一奇一偶的选择
		if(l!=-1&&r!=-1) flag=1;
		x=(x+1)%3;//取两奇数的情况
		for(int i=0; i<p[x].size(); i++)
		{
			if(mp.count(p[x][i]+1)||mp.count(p[x][i]-2))
			{
				flag=1;
				break;
			}
		}
		if(flag==1) cout <<"rqd"<<endl;
		else cout <<"His little girlfriend"<<endl;
	}
	
}
signed main()
{
	IOS;
	int __=1;
	cin>>__;
	while(__--) 
	{
		solve();
	}
} 

总结:

对于这类问题,可以用画思维导图,注意拆解的方法;然后很重点的是一定要多分类分堆;然后再每堆的思路需要理解一下,正难则反;

  • 4
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值