题意:
给出一个数列,现在有一种操作,可以任何一个a[i],用a[i] – a[i+1]和a[i]+a[i+1]替代a[i]和a[i+1]。
问现在需要最少多少次操作,使得整个数列的gcd大于1。
思路:
经过思考后发现,除非所有的数的gcd已经大于1,那么就必须把全部数字变为偶数。
变数字的时候,必须从第一个不是偶数的数字开始变化,每次都从下标最小的为奇数的数字开始变化。
如果是奇数,奇数,那么显然经过一次就可以全部变为偶数;
如果是奇数,偶数,那么必须经过两次才能全部变成偶数。
这题实际是贪心。
代码:
1 #include <iostream> 2 #include <string> 3 #include <algorithm> 4 using namespace std; 5 6 typedef long long ll; 7 const int inf = 0x3f3f3f3f; 8 9 const int N = 1e5 + 10; 10 11 int a[N]; 12 13 int gcd(int x,int y) 14 { 15 if (y == 0) return x; 16 else return gcd(y,x % y); 17 } 18 19 int main() 20 { 21 int n; 22 23 cin >> n; 24 25 for (int i = 1;i <= n;i++) 26 { 27 cin >> a[i]; 28 } 29 30 int _gcd = a[1]; 31 32 for (int i = 2;i <= n;i++) 33 { 34 _gcd = gcd(a[i],_gcd); 35 } 36 37 if (_gcd > 1) 38 { 39 return 0*printf("YES 0 "); 40 } 41 42 int ans = 0; 43 44 int p = 1; 45 46 while (p <= n) 47 { 48 if (a[p] % 2 == 0) 49 { 50 p++; 51 } 52 else 53 { 54 if (p < n && a[p+1] % 2) 55 { 56 ans++; 57 a[p] = a[p+1] = 2; 58 p++; 59 } 60 else if (p < n && a[p+1] % 2 == 0) 61 { 62 ans += 2; 63 a[p] = 2; 64 p++; 65 } 66 else 67 { 68 ans += 2; 69 p++; 70 } 71 } 72 } 73 74 //if (a[n] % 2) ans += 2; 75 76 cout << "YES" << endl << ans; 77 78 return 0; 79 }