[Codeforces] number theory (R1200) Part.9
题单:https://codeforces.com/problemset/page/6?tags=number%20theory,0-1200
1533A. Digits Sum
原题指路:https://codeforces.com/problemset/problem/1553/A
题意
对整数 x x x,定义 S ( x ) S(x) S(x)为 x x x的十进制表示的所有数码之和.称一个整数 x x x是好的,如果 S ( x + 1 ) < S ( x ) S(x+1)<S(x) S(x+1)<S(x).给定一个整数 n n n,求 [ 1 , n ] [1,n] [1,n]中好的数的个数.
有 t ( 1 ≤ t ≤ 1000 ) t\ \ (1\leq t\leq 1000) t (1≤t≤1000)组测试数据.每组测试数据输入一个整数 n ( 1 ≤ n ≤ 1 e 9 ) n\ \ (1\leq n\leq 1\mathrm{e}9) n (1≤n≤1e9).
思路
显然只有以 9 9 9结尾的整数符合条件,问题转化为求 [ 1 , n ] [1,n] [1,n]中以 9 9 9结尾的数的个数. a n s = ⌊ n + 1 10 ⌋ ans=\left\lfloor\dfrac{n+1}{10}\right\rfloor ans=⌊10n+1⌋,即先将 [ 1 , n ] [1,n] [1,n]中的数都 + 1 +1 +1,再考察其中 10 10 10的倍数的个数.
代码
void solve() {
int n; cin >> n;
cout << (n + 1) / 10 << endl;
}
int main() {
CaseT // 单测时注释掉该行
solve();
}
1562B. Scenes From a Memory
原题指路:https://codeforces.com/problemset/problem/1562/B
题意
给定一个十进制表示(不含前导零)有 k k k位的正整数 n n n,删除其中的一些数码(不能全部删除)使得剩下的数非素数.
有 t ( 1 ≤ t ≤ 1000 ) t\ \ (1\leq t\leq 1000) t (1≤t≤1000)组测试数据.每组测试数据第一行输入一个整数 k ( 1 ≤ k ≤ 50 ) k\ \ (1\leq k\leq 50) k (1≤k≤50).第二行输入一个整数 n ( 1 0 k − 1 ≤ n < 1 0 k ) n\ \ (10^{k-1}\leq n<10^k) n (10k−1≤n<10k).数据保证所有测试数据的 k k k之和不超过 1 e 4 1\mathrm{e}4 1e4.
对每组测试数据,先输出留下的数码个数,再输出删除后得到的非素数.数据保证有解,若有多组解,输出任一组.
思路
非素数即 1 1 1或偶数.
①若 n n n中包含数码 1 , 4 , 6 , 8 , 9 1,4,6,8,9 1,4,6,8,9,显然可只保留这些数码.
②若 n n n包含两个相同的数码,则它能被 11 11 11整除,可只保留这两个相同的数码.
③若 n n n包含数码 2 2 2或 5 5 5且它们不在首位,则只需将它们后面的数码都删除.
注意到还可只保留数码 2 2 2或 5 5 5及其前面一位,即构造一个两位数的答案.
④若上述情况都不满足,因数据保证有解,则 n n n中存在两数码之和是 3 3 3的倍数,
则由它们组成的两位数也是 3 3 3的倍数.
综上, k ≥ 2 k\geq 2 k≥2时,恒存在一个两位数的答案.
预处理出两位数的素数,枚举 n n n中剩下的两个数码即可,时间复杂度 O ( k 2 ) O(k^2) O(k2),所有测试数据的 k k k之和不超过 1 e 4 1\mathrm{e}4 1e4,可过.
代码
const int MAXN = 105;
bool prime[MAXN];
void init() {
for (int i = 2; i < MAXN; i++) {
prime[i] = true;
for (int j = 2; j * j <= i; j++)
if (i % j == 0) prime[i] = false;
}
}
void get(int n, string s) {
for (auto ch : s) {
if (ch == '1' || ch == '4' || ch == '6' || ch == '8' || ch == '9') {
cout << 1 << endl << ch << endl;
return;
}
}
for (int i = 0; i < n; i++) {
for (int j = i + 1; j < n; j++) {
int tmp = (s[i] - '0') * 10 + s[j] - '0';
if (!prime[tmp]) {
cout << 2 << endl << tmp << endl;
return;
}
}
}
}
void solve() {
init();
CaseT{
int n; string s; cin >> n >> s;
get(n, s);
}
}
int main() {
solve();
}
1581A. CQXYM Count Permutations
原题指路:https://codeforces.com/problemset/problem/1581/A
题意
求满足如下条件的长度为 2 n 2n 2n的 1 ∼ 2 n 1\sim 2n 1∼2n的排列的个数,答案对 1 e 9 + 7 1\mathrm{e}9+7 1e9+7取模:满足 p i < p i + 1 p_i<p_{i+1} pi<pi+1的下标 i i i的个数不少于 n n n.
有 t t t组测试数据.每组测试数据输入一个整数 n ( 1 ≤ n ≤ 1 e 5 ) n\ \ (1\leq n\leq 1\mathrm{e}5) n (1≤n≤1e5).数据保证所有测试数据的 n n n之和不超过 1 e 5 1\mathrm{e}5 1e5.
思路
称一个排列的值为满足 p i < p i + 1 p_i<p_{i+1} pi<pi+1的下标 i i i的个数.将一个值为 i i i的排列倒序可得值为 ( 2 n − i ) (2n-i) (2n−i)的排列,则所有值 < n <n <n的排列构成的集合与所有值 ≤ n \leq n ≤n的排列构成的集合间存在双射,则答案为每个集合的大小,即 a n s = 1 2 ⋅ ( 2 n ) ! ans=\dfrac{1}{2}\cdot (2n)! ans=21⋅(2n)!.
代码
const int MAXN = 2e5 + 5;
const int MOD = 1e9 + 7;
int fac[MAXN], ifac[MAXN];
void init() {
fac[0] = 1;
for (int i = 1; i < MAXN; i++) fac[i] = (ll)fac[i - 1] * i % MOD;
ifac[MAXN - 1] = qpow(fac[MAXN - 1], MOD - 2, MOD);
for (int i = MAXN - 1; i; i--) ifac[i - 1] = (ll)ifac[i] * i % MOD;
}
void solve() {
init();
CaseT {
int n; cin >> n;
cout << (ll)fac[2 * n] * qpow(2, MOD - 2, MOD) % MOD << endl;
}
}
int main() {
solve();
}
1583A. Windblume Ode
原题指路:https://codeforces.com/problemset/problem/1583/A
题意
给定一个包含 n n n个相异元素的序列 a 1 , ⋯ , a n a_1,\cdots,a_n a1,⋯,an,从其中选出最多个元素,使得它们之和非素数,输出选择的元素的个数和下标.可以证明必有解.
有 t ( 1 ≤ t ≤ 100 ) t\ \ (1\leq t\leq 100) t (1≤t≤100)组测试数据.每组测试数据第一行输入一个整数 n ( 3 ≤ n ≤ 100 ) n\ \ (3\leq n\leq 100) n (3≤n≤100).第二行输入 n n n个相异的整数 a 1 , ⋯ , a n ( 1 ≤ a i ≤ 200 ) a_1,\cdots,a_n\ \ (1\leq a_i\leq 200) a1,⋯,an (1≤ai≤200).
思路
(1) a i ( 1 ≤ i ≤ n ) a_i\ \ (1\leq i\leq n) ai (1≤i≤n)都为偶数时,显然它们之和是 > 2 >2 >2的偶数,取整个序列即可.
(2) a i ( 1 ≤ i ≤ n ) a_i\ \ (1\leq i\leq n) ai (1≤i≤n)不全为偶数时,至少存在一个奇数.
①若所有元素之和为偶数,显然该偶数 > 2 >2 >2,取整个序列即可.
②若所有元素之和为奇数,减去一个奇数将其转化为情况①,显然得到的偶数 > 2 >2 >2.
代码
bool check(int x) { // 判断x是否是素数
if (x <= 2) return x == 2;
for (int i = 2; i <= sqrt(x); i++)
if (x % i == 0) return false;
return true;
}
void solve() {
int n; cin >> n;
vi a(n + 1);
int odd = -1; // 奇数的下标
int sum = 0; // 元素之和
for (int i = 1; i <= n; i++) {
cin >> a[i];
sum += a[i];
if (odd == -1 && a[i] & 1) odd = i;
}
if (check(sum)) {
cout << n - 1 << endl;
for (int i = 1; i <= n; i++)
if (i != odd) cout << i << ' ';
cout << endl;
}
else {
cout << n << endl;
for (int i = 1; i <= n; i++) cout << i << ' ';
cout << endl;
}
}
int main() {
CaseT // 单测时注释掉该行
solve();
}
1593D1. All are Same
原题指路:https://codeforces.com/problemset/problem/1593/D1
题意
给定一个长度为 n n n的序列 a 1 , ⋯ , a n a_1,\cdots,a_n a1,⋯,an,选定一个正整数 k k k,每次操作选择一个下标 i ( 1 ≤ i ≤ n ) i\ \ (1\leq i\leq n) i (1≤i≤n),令 a i − = k a_i-=k ai−=k.经若干次(可能为零次)操作后序列中所有元素相等,求 k k k的最大值.若 k k k可任意大,输出 − 1 -1 −1.
有 t ( 1 ≤ t ≤ 10 ) t\ \ (1\leq t\leq 10) t (1≤t≤10)组测试数据.每组测试数据第一行输入一个偶数 n ( 4 ≤ n ≤ 40 ) n\ \ (4\leq n\leq 40) n (4≤n≤40).第二行输入 n n n个整数 a 1 , ⋯ , a n ( − 1 e 6 ≤ a i ≤ 1 e 6 ) a_1,\cdots,a_n\ \ (-1\mathrm{e}6\leq a_i\leq 1\mathrm{e}6) a1,⋯,an (−1e6≤ai≤1e6).数据保证所有测试数据的 n n n之和不超过 100 100 100.
思路
①若序列中所有元素相等,显然 k k k可任意大.
②若序列中元素不全相等,设 a m i n a_{min} amin是序列中最小的元素,显然 k = gcd 1 ≤ i ≤ n ( a i − a m i n ) \displaystyle k=\gcd_{1\leq i\leq n} (a_i-a_{min}) k=1≤i≤ngcd(ai−amin).
代码
void solve() {
int n; cin >> n;
vi a(n);
bool different = false; // 记录序列a[]是否所有元素都相等
int minnum = INF;
for (int i = 0; i < n; i++) {
cin >> a[i];
minnum = min(minnum, a[i]);
different |= a[i] != a[0];
}
if (!different) cout << -1 << endl;
else {
int ans = 0;
for (int i = 0; i < n; i++) ans = gcd(ans, a[i] - minnum);
cout << ans << endl;
}
}
int main() {
CaseT // 单测时注释掉该行
solve();
}
1605A. A.M. Deviation
原题指路:https://codeforces.com/problemset/problem/1605/A
题意
对三个整数 a 1 , a 2 , a 3 a_1,a_2,a_3 a1,a2,a3,定义它们的算术平均偏差 d ( a 1 , a 2 , a 3 ) = ∣ a 1 + a 3 − 2 a 2 ∣ d(a_1,a_2,a_3)=|a_1+a_3-2a_2| d(a1,a2,a3)=∣a1+a3−2a2∣.现有操作:选择两个下标 i , j ( i , j ∈ { 1 , 2 , 3 } , i ≠ j ) i,j\ \ (i,j\in\{1,2,3\},i\neq j) i,j (i,j∈{1,2,3},i=j),令 a i + + , a j − − a_i++,a_j-- ai++,aj−−.求经过若干次(可能为零次)操作后 d ( a 1 , a 2 , a 3 ) d(a_1,a_2,a_3) d(a1,a2,a3)的最小值.
有 t ( 1 ≤ t ≤ 5000 ) t\ \ (1\leq t\leq 5000) t (1≤t≤5000)组测试数据.每组测试数据输入三个整数 a 1 , a 2 , a 3 ( 1 ≤ a 1 , a 2 , a 3 ≤ 1 e 8 ) a_1,a_2,a_3\ \ (1\leq a_1,a_2,a_3\leq 1\mathrm{e}8) a1,a2,a3 (1≤a1,a2,a3≤1e8).
思路
①令 a 1 + + , a 3 − − a_1++,a_3-- a1++,a3−−或令 a 3 + + , a 1 − − a_3++,a_1-- a3++,a1−−都不改变 d ( a 1 , a 2 , a 3 ) d(a_1,a_2,a_3) d(a1,a2,a3).
②令 a 1 ( a 3 ) + + , a 2 − − a_1(a_3)++,a_2-- a1(a3)++,a2−−会使得 d ( a 1 , a 2 , a 3 ) + 3 d(a_1,a_2,a_3)+3 d(a1,a2,a3)+3.
③令 a 1 ( a 3 ) − − , a 2 + + a_1(a_3)--,a_2++ a1(a3)−−,a2++会使得 d ( a 1 , a 2 , a 3 ) − 3 d(a_1,a_2,a_3)-3 d(a1,a2,a3)−3.
注意到若加减 3 3 3的倍数次,则 d ( a 1 , a 2 , a 3 ) d(a_1,a_2,a_3) d(a1,a2,a3)的值在模 3 3 3意义下不变:
①若 d ( a 1 , a 2 , a 3 ) ≡ 0 ( m o d 3 ) d(a_1,a_2,a_3)\equiv 0\ \ (\mathrm{mod}\ 3) d(a1,a2,a3)≡0 (mod 3),则 d ( a 1 , a 2 , a 3 ) d(a_1,a_2,a_3) d(a1,a2,a3)的最小值为 ∣ 0 ∣ = 0 |0|=0 ∣0∣=0.
②若 d ( a 1 , a 2 , a 3 ) ≡ 1 ( m o d 3 ) d(a_1,a_2,a_3)\equiv 1\ \ (\mathrm{mod}\ 3) d(a1,a2,a3)≡1 (mod 3),则 d ( a 1 , a 2 , a 3 ) d(a_1,a_2,a_3) d(a1,a2,a3)的最小值为 ∣ 1 ∣ = 1 |1|=1 ∣1∣=1.
③若 d ( a 1 , a 2 , a 3 ) ≡ 2 ( m o d 3 ) d(a_1,a_2,a_3)\equiv 2\ \ (\mathrm{mod}\ 3) d(a1,a2,a3)≡2 (mod 3),则 d ( a 1 , a 2 , a 3 ) d(a_1,a_2,a_3) d(a1,a2,a3)的最小值为 ∣ 2 − 3 ∣ = 1 |2-3|=1 ∣2−3∣=1.
综上,若初始时 d ( a 1 , a 2 , a 3 ) d(a_1,a_2,a_3) d(a1,a2,a3)是 3 3 3的倍数,则 a n s = 0 ans=0 ans=0;否则 a n s = 1 ans=1 ans=1.
代码
void solve() {
int sum = 0;
for (int i = 0; i < 3; i++) {
int a; cin >> a;
sum += a;
}
cout << (sum % 3 ? 1 : 0) << endl;
}
int main() {
CaseT // 单测时注释掉该行
solve();
}
1609A. Divide and Multiply
原题指路:https://codeforces.com/problemset/problem/1609/A
题意
给定一个长度为 n n n的序列 a 1 , ⋯ , a n a_1,\cdots,a_n a1,⋯,an.现有操作:选一对下标 i , j ( 1 ≤ i , j ≤ n , i ≠ j ) i,j\ \ (1\leq i,j\leq n,i\neq j) i,j (1≤i,j≤n,i=j),其中 a i a_i ai是 2 2 2的倍数,令 a i / = 2 , a j ∗ = 2 a_i/=2,a_j*=2 ai/=2,aj∗=2.求经若干次(可能为零次)操作后序列元素之和的最大值.
有 t ( 1 ≤ t ≤ 1 e 4 ) t\ \ (1\leq t\leq 1\mathrm{e}4) t (1≤t≤1e4)组测试数据.每组测试数据第一行输入一个整数 n ( 1 ≤ n ≤ 15 ) n\ \ (1\leq n\leq 15) n (1≤n≤15).第二行输入 n n n个整数 a 1 , ⋯ , a n ( 1 ≤ a i < 16 ) a_1,\cdots,a_n\ \ (1\leq a_i<16) a1,⋯,an (1≤ai<16).
思路
显然应让 a [ ] a[] a[]中最大的数乘尽量多次 2 2 2,能乘的最大次数即其他元素能整除 2 2 2的最大次数.
代码
void solve() {
int n; cin >> n;
vl a(n);
int s = 0; // 除以2的次数
for (auto& ai : a) {
cin >> ai;
while (ai % 2 == 0) {
ai >>= 1;
s++;
}
}
sort(all(a), greater<int>());
a[0] *= ((ll)1 << s);
ll sum = 0;
for (int i = 0; i < n; i++) sum += a[i];
cout << sum << endl;
}
int main() {
CaseT // 单测时注释掉该行
solve();
}
1617B. GCD Problem
原题指路:https://codeforces.com/problemset/problem/1617/B
题意 ( 2 s 2\ \mathrm{s} 2 s)
给定一个正整数 n n n,求三个相异的正整数 a , b , c s . t . a + b + c = n , gcd ( a , b ) = c a,b,c\ s.t.\ a+b+c=n,\gcd(a,b)=c a,b,c s.t. a+b+c=n,gcd(a,b)=c.
有 t ( 1 ≤ t ≤ 1 e 5 ) t\ \ (1\leq t\leq 1\mathrm{e}5) t (1≤t≤1e5)组测试数据.每组测试数据输入一个整数 n ( 10 ≤ n ≤ 1 e 9 ) n\ \ (10\leq n\leq 1\mathrm{e}9) n (10≤n≤1e9).
思路I
注意到 n ≥ 10 n\geq 10 n≥10时,固定 c = 1 c=1 c=1必有解.
枚举 a = 2 , 3 , ⋯ a=2,3,\cdots a=2,3,⋯,对每个 a a a,令 b = n − a − 1 b=n-a-1 b=n−a−1,检查 gcd ( a , b ) = 1 \gcd(a,b)=1 gcd(a,b)=1是否成立.该方法不会超时是因为至少存在一个素数 p ≤ 29 s . t . p ∤ ( n − 1 ) p\leq 29\ s.t.\ p\not\mid (n-1) p≤29 s.t. p∣(n−1).
代码I
void solve() {
int n; cin >> n;
for (int a = 2;; a++) {
int b = n - a - 1;
if (a != b && gcd(a, b) == 1) {
cout << a << ' ' << b << ' ' << 1 << endl;
return;
}
}
}
int main() {
CaseT // 单测时注释掉该行
solve();
}
思路II
随机 a a a的值,其余同思路I.
代码II
mt19937 rng(time(0));
void solve() {
int n; cin >> n;
while (true) {
int a = uniform_int_distribution<int>(2, n - 2)(rng);
int b = n - a - 1;
if (a != 1 && b != 1 && a != b && gcd(a, b) == 1) {
cout << a << ' ' << b << ' ' << 1 << endl;
return;
}
}
}
int main() {
CaseT // 单测时注释掉该行
solve();
}
思路III
构造:
① n ≡ 0 ( m o d 2 ) n\equiv 0\ \ (\mathrm{mod}\ 2) n≡0 (mod 2)时,取 ( a , b , c ) = ( n − 3 , 2 , 1 ) (a,b,c)=(n-3,2,1) (a,b,c)=(n−3,2,1).
② n ≡ 1 ( m o d 4 ) n\equiv 1\ \ (\mathrm{mod}\ 4) n≡1 (mod 4)时,取 ( a , b , c ) = ( ⌊ n 2 ⌋ − 1 , ⌊ n 2 ⌋ + 1 , 1 ) (a,b,c)=\left(\left\lfloor\dfrac{n}{2}\right\rfloor-1,\left\lfloor\dfrac{n}{2}\right\rfloor+1,1\right) (a,b,c)=(⌊2n⌋−1,⌊2n⌋+1,1).
③ n ≡ 3 ( m o d 4 ) n\equiv 3\ \ (\mathrm{mod}\ 4) n≡3 (mod 4)时,取 ( a , b , c ) = ( ⌊ n 2 ⌋ − 2 , ⌊ n 2 ⌋ + 2 , 1 ) (a,b,c)=\left(\left\lfloor\dfrac{n}{2}\right\rfloor-2,\left\lfloor\dfrac{n}{2}\right\rfloor+2,1\right) (a,b,c)=(⌊2n⌋−2,⌊2n⌋+2,1).
代码III
void solve() {
int n; cin >> n;
if (n % 2 == 0) cout << n - 3 << ' ' << 2 << ' ' << 1 << endl;
else if (n % 4 == 1) cout << n / 2 - 1 << ' ' << n / 2 + 1 << ' ' << 1 << endl;
else cout << n / 2 - 2 << ' ' << n / 2 + 2 << ' ' << 1 << endl;
}
int main() {
CaseT // 单测时注释掉该行
solve();
}
1629B. GCD Arrays
原题指路:https://codeforces.com/problemset/problem/1629/B
题意
给定两整数 l , r l,r l,r,定义序列 a [ ] a[] a[]为 l , l + 1 , ⋯ , r l,l+1,\cdots, r l,l+1,⋯,r.现有操作:选择 a a a中的两元素,将它们的替换为它们之积.问至多 k k k次操作后能否使得序列的所有元素的 gcd > 1 \gcd>1 gcd>1,若能则输出"YES";否则输出"NO".
有 t ( 1 ≤ t ≤ 1 e 5 ) t\ \ (1\leq t\leq 1\mathrm{e}5) t (1≤t≤1e5)组测试数据.每组测试数据输入三个整数 l , r , k ( 1 ≤ l ≤ r ≤ 1 e 9 , 0 ≤ k ≤ r − 1 ) l,r,k\ \ (1\leq l\leq r\leq 1\mathrm{e}9,0\leq k\leq r-1) l,r,k (1≤l≤r≤1e9,0≤k≤r−1).
思路
显然每次操作可合并两个数的素因子.为使得所有元素的 gcd > 1 \gcd>1 gcd>1且步数尽量少,因序列 a [ ] a[] a[]是连续整数,故取 gcd = 2 \gcd=2 gcd=2最优,所需的最少步数为序列中奇数的个数,即序列长度 − - −序列中偶数的个数,具体地, s t e p = ( r − l + 1 ) − ( ⌊ r 2 ⌋ − ⌊ l − 1 2 ⌋ ) step=(r-l+1)-\left(\left\lfloor\dfrac{r}{2}\right\rfloor-\left\lfloor\dfrac{l-1}{2}\right\rfloor\right) step=(r−l+1)−(⌊2r⌋−⌊2l−1⌋).
注意特判 l = r l=r l=r的情况,此时若 l = r = 1 l=r=1 l=r=1,答案为"NO";否则答案为"YES";
代码
void solve() {
int l, r, k; cin >> l >> r >> k;
if (l == r) cout << (l == 1 ? "NO" : "YES") << endl;
else {
int ans = (r - l + 1) - (r / 2 - (l - 1) / 2);
cout << (k >= ans ? "YES" : "NO") << endl;
}
}
int main() {
CaseT // 单测时注释掉该行
solve();
}
1656C. Make Equal With Mod
原题指路:https://codeforces.com/problemset/problem/1656/C
题意
给定一个长度为 n n n的序列 a 1 , ⋯ , a n a_1,\cdots,a_n a1,⋯,an.现有操作:选定一个整数 x ≥ 2 x\geq 2 x≥2,将所有 a i % = x ( 1 ≤ i ≤ n ) a_i\%=x\ \ (1\leq i\leq n) ai%=x (1≤i≤n).问若干次(可能为零次)操作后是否能使得序列中所有元素相等,若能则输出"YES";否则输出"NO".
有 t ( 1 ≤ t ≤ 1 e 4 ) t\ \ (1\leq t\leq 1\mathrm{e}4) t (1≤t≤1e4)组测试数据.每组测试数据第一行输入一个整数 n ( 1 ≤ n ≤ 1 e 5 ) n\ \ (1\leq n\leq 1\mathrm{e}5) n (1≤n≤1e5).第二行输入 n n n个整数 a 1 , ⋯ , a n ( 0 ≤ a i ≤ 1 e 9 ) a_1,\cdots,a_n\ \ (0\leq a_i\leq 1\mathrm{e}9) a1,⋯,an (0≤ai≤1e9).数据保证所有测试数据的 n n n之和不超过 2 e 5 2\mathrm{e}5 2e5.
思路
①若序列中不存在 1 1 1,则每次取 x = max 1 ≤ i ≤ n a i \displaystyle x=\max_{1\leq i\leq n}a_i x=1≤i≤nmaxai,即每次将序列中的最大值置为 0 0 0,答案为"YES".
②若序列中存在 1 1 1且不存在相邻的两数 m , m + 1 m,m+1 m,m+1,则每次取 x = max 1 ≤ i ≤ n a i − 1 \displaystyle x=\max_{1\leq i\leq n}a_i-1 x=1≤i≤nmaxai−1,
最终将所有元素变为都是 1 1 1,答案为"YES".
③若序列中存在 1 1 1且存在相邻的两数 m , m + 1 m,m+1 m,m+1,则将其中一个数变为 1 1 1时会使得另一个数变为 0 0 0,
故无法将所有元素变为都相等,答案为"NO".
代码
int main() {
CaseT{
int n; cin >> n;
vi a(n);
bool same = true; // 记录是否所有元素都相等
for (int i = 0; i < n; i++) {
cin >> a[i];
if (a[i] != a[0]) same = false;
}
if (same || n == 1) {
cout << "YES" << endl;
continue;
}
sort(a.begin(), a.end());
bool one = false; // 记录数组中是否有1
bool adjancent = false; // 记录数组中是否有相邻的数
for (int i = 0; i < n; i++) {
if (a[i] == 1) one = true;
if (i < n - 1 && a[i] + 1 == a[i + 1]) adjancent = true;
}
cout << ((one && adjancent) ? "NO" : "YES") << endl;
}
}