P14292 [JOI2024 预选赛 R2] 卡牌游戏 / Card Game 2 题解

题目链接

P14292 [JOI2024 预选赛 R2] 卡牌游戏 / Card Game 2

题目描述

比太郎持有 \(N\) 张卡片,第 \(i\) 张卡片(\(1 \le i \le N\))上写有一个整数 \(A_i\)。他希望从这些卡片中选出满足以下条件的三张卡片。

条件:

  • 选出的三张卡片上所写的整数彼此相差 \(3\)。更精确地说,选出的三张卡片上的整数可以表示为某个整数 \(x\),以及 \(x+3\)\(x+6\)

例如,若比太郎持有 \(5\) 张卡片,上面分别写着 \(2, 4, 5, 7, 10\),则选择写有 \(4, 7, 10\) 的三张卡片即可满足条件。

给定比太郎所持卡片的信息,请编写一个程序,判断是否能够选出满足条件的三张卡片。

输入格式

输入以如下格式给出:

\(N\)

\(A_1\ A_2\ \cdots\ A_N\)

输出格式

若能够选出满足条件的三张卡片,则输出 Yes;否则输出 No

输入输出样例 #1

输入 #1

3
2 5 8

输出 #1

Yes

输入输出样例 #2

输入 #2

4
1 4 6 4

输出 #2

No

输入输出样例 #3

输入 #3

8
9 8 11 1 1 6 10 4

输出 #3

No

输入输出样例 #4

输入 #4

20
2 15 4 30 6 8 11 27 14 3 16 26 19 2 23 21 18 13 28 6

输出 #4

Yes

说明/提示

样例解释

  • 样例 \(1\) 可以选择 \(2,5,8\)
  • 样例 \(2,3\) 不存在可以选择的情况;
  • 样例 \(4\) 可以选择 \(15,18,21\)

约束

  • \(3 \le N \le 200\,000\)
  • \(1 \le A_i \le 200\,000\)\(1 \le i \le N\))。
  • 所有输入的值均为整数。

子任务

  1. (20 分)\(N = 3\)
  2. (20 分)\(A_i \le 7\)\(1 \le i \le N\))。
  3. (30 分)\(N \le 100\)
  4. (30 分)无额外约束。

题解

题意

给出一个含有 N 个数的数组,判断是否能够选出满足彼此相差 \(3\)的三个整数

思路

  • \(3 \le N \le 200\,000\)

所以三重循环肯定是不行的。
但是,我们又知道了

  • \(1 \le A_i \le 200\,000\)\(1 \le i \le N\))。

所以可以运用桶数组,用 m 记录最大值,从 1 到 m-6 遍历一遍开始判断:如果其中出现了 x、x+3 和 x+6 都存在的情况,直接cout<<"Yes",然后return 0

AC代码:

#include<bits/stdc++.h>
using namespace std;
#define int long long
bool z[100000005];//布尔类型,避免MLE
int a[111];
signed main(){
	int t,n,m,i,x,j,k,l;
	// for(cin>>t;t>0;t--){
		cin>>n;
		if(n<=100){//n<=100时三重循环不会TLE
			for(i=1;i<=n;i++){
				cin>>a[i];
			}
			sort(a+1,a+n+1);
			x=0;
			for(j=1;j<=n-2;j++){
				for(k=j+1;k<=n-1;k++){
					for(l=k+1;l<=n;l++){
						if(a[k]-a[j]==3&&a[l]-a[k]==3){
							x=1;
							break;
						}	
					}
					if(x)
						break;	
				}
				if(x)
					break;
			}
			if(x)
				cout<<"Yes\n";
			else
				cout<<"No\n";
		}
		else{//桶数组
			m=0;
			for(i=1;i<=n;i++){
				cin>>x;
				z[x]=1;
				m=max(m,x);
			}
			x=0;
			for(i=1;i<=m-6;i++){
				if(z[i]&&z[i+3]&&z[i+6]){
					x=1;
					break;
				}
			}
			if(x)
				cout<<"Yes\n";
			else
				cout<<"No\n";
		}
	// }	
//	for(cin>>t;t>0;t--){//二分不会写>﹏<
//		cin>>n;
//		for(i=1;i<=n;i++){
//			cin>>a[i];
//		}
//		sort(a+1,a+n+1);
//		bool x3=0,x6=0;
//		for(i=1;i<=n;i++){
//			x3=0,x6=0;
//			int s=i+1,b=n;
//			while(s<b){
//				int sb=(s+b)/2;
//				if(a[sb]>a[i]+3){
//					b=sb-1;
//				}
//				else if(a[sb]<a[i]+3){
//					s=sb+1;
//				}
//				else{
//					x3=1;
//					break;
//				}
//			}
//			if(!x3)
//				continue;
//			while(s<b){
//				int sb=(s+b)/2;
//				if(a[sb]>a[i]+6){
//					b=sb-1;
//				}
//				else if(a[sb]<a[i]+6){
//					s=sb+1;
//				}
//				else{
//					x6=1;
//					break;
//				}
//			}
//			if(x6){
//				break;
//			}
//		}
//		if(x6)
//			cout<<"Yes\n";
//		else
//			cout<<"No\n";
//	}
	return 0;
}
posted @ 2026-05-06 11:37  huan9178  阅读(8)  评论(0)    收藏  举报