CodeForces - 892 C - Pride【GCD思维】
2017-11-19 16:21
417 查看
ou have an array a with length n, you can perform operations. Each operation is like this: choose two adjacent elements from a, say x and y, and replace one of them with gcd(x, y), where gcd denotes the greatest common divisor.
What is the minimum number of operations you need to make all of the elements equal to 1?
Input
The first line of the input contains one integer n (1 ≤ n ≤ 2000) — the number of elements in the array.
The second line contains n space separated integers a1, a2, …, an (1 ≤ ai ≤ 109) — the elements of the array.
Output
Print -1, if it is impossible to turn all numbers to 1. Otherwise, print the minimum number of operations needed to make all numbers equal to 1.
Examples
input
5
2 2 3 4 6
output
5
input
4
2 4 6 8
output
-1
input
3
2 6 9
output
4
Note
In the first sample you can turn all numbers to 1 using the following 5 moves:
[2, 2, 3, 4, 6].
[2, 1, 3, 4, 6]
[2, 1, 3, 1, 6]
[2, 1, 1, 1, 6]
[1, 1, 1, 1, 6]
[1, 1, 1, 1, 1]
We can prove that in this case it is not possible to make all numbers one using less than 5 moves.
题意:找两个相邻的数x,y,可用GCD(x, y)替代其中的一个(这是一步操作),问你能否将整个序列的元素全部变为1,能的话输出最小操作次数,否则输出-1;
思路:主要是找到第一个1的出现!只要序列有一个1,那么操作次数就是:n - 1,有t个1,那么操作次数就是n - t,根据这个可以特判一下;然后,可以求第i个元素的【i + 1, n】这个区间内最少操作次数对于GCD(a[i], a[j]) = 1,对每一个点都相同处理,结果:最少的操作次数 + n - 1。
What is the minimum number of operations you need to make all of the elements equal to 1?
Input
The first line of the input contains one integer n (1 ≤ n ≤ 2000) — the number of elements in the array.
The second line contains n space separated integers a1, a2, …, an (1 ≤ ai ≤ 109) — the elements of the array.
Output
Print -1, if it is impossible to turn all numbers to 1. Otherwise, print the minimum number of operations needed to make all numbers equal to 1.
Examples
input
5
2 2 3 4 6
output
5
input
4
2 4 6 8
output
-1
input
3
2 6 9
output
4
Note
In the first sample you can turn all numbers to 1 using the following 5 moves:
[2, 2, 3, 4, 6].
[2, 1, 3, 4, 6]
[2, 1, 3, 1, 6]
[2, 1, 1, 1, 6]
[1, 1, 1, 1, 6]
[1, 1, 1, 1, 1]
We can prove that in this case it is not possible to make all numbers one using less than 5 moves.
题意:找两个相邻的数x,y,可用GCD(x, y)替代其中的一个(这是一步操作),问你能否将整个序列的元素全部变为1,能的话输出最小操作次数,否则输出-1;
思路:主要是找到第一个1的出现!只要序列有一个1,那么操作次数就是:n - 1,有t个1,那么操作次数就是n - t,根据这个可以特判一下;然后,可以求第i个元素的【i + 1, n】这个区间内最少操作次数对于GCD(a[i], a[j]) = 1,对每一个点都相同处理,结果:最少的操作次数 + n - 1。
#include <cstdio> #include <cmath> #include <algorithm> using namespace std; typedef long long LL; const LL INF = 1e9; const LL MAXN = 2e3 + 100; LL cnt[MAXN]; LL GCD(LL a, LL b) { return !b ? a : GCD(b, a % b); } int main() { LL n, gcd; LL res = 0; scanf("%lld", &n); for(int i = 1; i <= n; i++) { scanf("%lld", &cnt[i]); if(cnt[i] == 1) res++; if(i == 1) gcd = cnt[i]; else { gcd = GCD(gcd, cnt[i]); } } if(res) { printf("%lld\n", n - res); return 0; } if(gcd != 1) { printf("-1\n"); return 0; } LL ans = INF; for(int i = 1; i <= n; i++) { LL minn = INF; gcd = cnt[i]; for(LL j = i + 1; j <= n; j++) { gcd = GCD(gcd, cnt[j]); //枚举区间,枚举两点不对,gcd时时更新 ; if(gcd == 1) { minn = j - i; break; } } ans = min(minn, ans); } if(ans < INF) printf("%lld\n", ans + n - 1); else printf("-1\n"); return 0; } /* 3 42 15 35 */
相关文章推荐
- Codeforces 894C - Marco and GCD Sequence 【GCD+思维】
- Codeforces 892 D. Gluttony (思维)
- Codeforces 892 C.Pride
- Codeforces 892 C. Pride (枚举)
- Codeforces 803C Maximal GCD【思维】
- Codeforces 359D Pair of Numbers【思维+二分+区间Gcd+区间最小值RMQ】
- Codeforces 892 C. Pride
- CodeForces 581C - GCD Table(思维)
- Codeforces-891A Pride(GCD&&思维)
- codeforces 892C Pride(gcd)
- 【CodeForces】366A - Dima and Guards(思维)
- Codeforces 611F 思维
- [思维]CodeForces 135B
- CodeForces - 729D Sea Battle(思维题)
- 【Codeforces】338 D GCD Table 中国剩余定理(孙子定理)
- CodeForces - 711C Coloring Trees(DP)(思维)
- Codeforces 22B Bargaining Table【暴力+思维】
- Codeforces 763B Timofey and rectangles(四色定理)(思维)
- codeforces 719B:Anatoly and Cockroaches(思维)
- CodeForces - 834C The Meaningless Game 思维