题目链接:
Problem - 798C - Codeforces
题目描述
迈克有一个长度为n的序列 A = [a1, a2, ..., an] 。如果序列 B = [b1, b2, ..., bn] 中所有元素的 gcd 都大于 1 ,他就认为这个序列 B = [b1, b2, ..., bn] 很美,即gcd(b1, b2, ..., bn)>1。
Mike 想改变他的序列,使其更加美观。他可以选择一个索引 i ( 1 ≤ i < n ),删除数字 ai, ai + 1 ,并按照这个顺序将数字 a1− ai + 1,ai+ai+1 放到它们的位置上。他希望进行尽可能少的运算。如果可能,请找出使数列 A 变美的最少运算次数,或者告诉他不可能这样做。gcd(b1, b2, ..., bn)是最大的非负数 d,使得 ∗bi∗ 除于 d 为 0 ( 1 ≤ i ≤ n )。
输入描述
第一行包含一个整数n( 2 ≤n≤ 100 000 ) - 序列 A 的长度。
第二行包含 n 个空格分隔的整数 a1, a2, ..., an(1 ≤ ai ≤ 109) - 序列 A 的元素。
输出描述
如果可以通过执行上述操作使序列 A 变美,则在第一行输出"YES"(不带引号),否则输出"NO"(不带引号)。
如果答案是"YES",则输出使序列 A 优美所需的最小步数
示例
输入1
text
输出1
text
输入2
text
输出2
text
输入3
text
输出3
text
说明
在第一个示例中,你只需移动一次,就可以得到序列 [0, 2] ,其中有gcd(0,2)=2 。
在第二个示例中,序列中的 gcd 已经大于 1 。
题解
这是一道思维题,不管数据怎么样,输出结果都是"YES"。如果 gcd(b1, b2, ..., bn)>1,直接输出0,否则 gcd(b1, b2, ..., bn)=2。
先来解释一下为什么输出肯定是"YES":
- 对于两相邻的数a,b ,如果要进行操作,操作一次后变为 a-b,a+b,在操作一次变成 -2b,2a,也就是说,只要操作足够多的次数,最后这个数列gcd(b1, b2, ..., bn) 一定可以到达2,也就是输出"YES"。
下面来证明为什么要操作的话最终的 gcd(b1, b2, ..., bn) 一定是2:
下面给出完整代码:
(这次代码写的比较垃圾,建议根据前面的思维证明自己写。)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66
| #include <bits/stdc++.h> using namespace std; long long a[100005] = {0};
int main() { ios::sync_with_stdio(false); cin.tie(0); cout.tie(0); bool flag = true; int n; cin >> n; for (int i = 1; i <= n; i++) { cin >> a[i]; } long long temp = __gcd(a[1], a[2]); if (temp > 1) { for (int i = 2; i < n; i++) { if (__gcd(a[i], a[i + 1]) != 1 && (__gcd(a[i], a[i + 1]) % temp == 0 || temp % __gcd(a[i], a[i + 1]) == 0)) { temp = min(temp, __gcd(a[i], a[i + 1])); continue; } else { flag = false; break; } } } cout << "YES" << "\n"; if (flag && temp > 1) { cout << 0; return 0; } long long ans = 0; for (int i = 1; i < n; i++) { if (a[i] % 2 == 1 && a[i + 1] % 2 == 1) { ans++; long long b = a[i]; long long c = a[i + 1]; a[i] = b - c; a[i + 1] = b + c; } else if (a[i] % 2 == 1 && a[i + 1] % 2 == 0) { ans += 2; long long b = a[i]; long long c = a[i + 1]; a[i] = -2 * c; a[i + 1] = 2 * b; } } if (a[n] % 2 == 1) { ans += 2; } cout << ans; return 0; }
|