「MYOI-R3」消消乐
题目背景
upd 2024/5/12 18:14:增加了两组 Hack 数据,位于 Subtask 1,分值为 0 0 0 分。
upd 2024/5/12 21:27:增加了一组 Hack 数据,位于 Subtask 1,分值为 0 0 0 分。
题目描述
给定一个长度为 n n n 的数列 a a a。
定义一次操作为选择三个整数 x , y , z ∈ [ 1 , n ] x,y,z\in[1,n] x,y,z∈[1,n],满足 gcd ( a x , a y ) = a z \gcd(a_x,a_y)=a_z gcd(ax,ay)=az 且 x , y , z x,y,z x,y,z 两两不同,接着消除 a z a_z az(即之后的操作中不能再选择 a z a_z az 了)。
问经过若干次操作后可否消除数列 a 1 ∼ a n a_1\sim a_n a1∼an 中的 n − 2 n-2 n−2 个数?
输入格式
第一行一个正整数 T T T,表示数据组数。
对于每组数据,
第一行一个正整数 n n n。
第二行 n n n 个正整数 a i a_i ai。
输出格式
对于每组数据,一行一个字符串 Yes
或 No
。
样例 #1
样例输入 #1
2
3
1 2 3
3
1 2 4
样例输出 #1
Yes
No
提示
样例解释:
- 对于第一组数据,可以通过 ( 2 , 3 ) (2,3) (2,3) 消除 1 1 1。
- 对于第二组数据,可以证明无解。
数据范围:
本题共有 20 20 20 个测试点,每个测试点的分值均为 5 5 5 分。
对于 100 % 100\% 100% 的数据, 1 ≤ T ≤ 1 0 5 1\le T\le 10^5 1≤T≤105, 2 ≤ n ≤ 1 0 6 2\leq n \leq 10^6 2≤n≤106, 2 ≤ ∑ n ≤ 1 0 6 2 \le \sum n\le 10^6 2≤∑n≤106, 1 ≤ a i ≤ 1 0 9 1\le a_i\le 10^9 1≤ai≤109。
思路
- 我们可以先对这个序列排序一下,然后我们可以发现: g c d ( a , b ) ≤ m i n ( a , b ) gcd(a,b)\le min(a,b) gcd(a,b)≤min(a,b),这说明什么?说明最终剩下的两个数就是这个数组中最大的两个数。
- 那么我们就可以枚举数组,看看 g c d ( n , n − 1 ) = w i gcd(n,n-1)=w_i gcd(n,n−1)=wi,(其中 n n n 为数组长度, w i w_i wi 为数组元素)只要当这个条件不成立,那么就无解了。(仔细想想可以知道的)
参考:
代码
#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
const int N = 1e6+10;
int w[N];
bool f;
int T,n;
int gcd(int a,int b){
return b?gcd(b,a%b):a;
}
int main(){
cin>>T;
while(T--){
f=false;
cin>>n;
for(int i=1;i<=n;i++)cin>>w[i];
if(n==2){
puts("Yes");
continue;
}
sort(w+1,w+1+n);
int k=gcd(w[n],w[n-1]);
//就是如果排完序当前的gcd(a,b)!=c,那么此时的c不会再被其他的数更新了
for(int i=1;i<n-1;i++){
if(k!=w[i]){
f=true;
break;
}
}
if(!f){
puts("Yes");
}else{
puts("No");
}
}
return 0;
}