嗯...
题目链接:https://www.luogu.org/problemnew/show/CF798C
这道题首先要会写gcd..也类似一种找规律吧...
问题的操作是在两个数的基础上进行的:
那么我们不妨只考虑两个数的操作,手写几组数据不难发现,所有写出来的两个数A.B,都会在至多两次操作内完成任务。那么我们可以考虑其性质:
两个数A.B.无非四种情况:
奇数,奇数--------------->操作后变成 偶数,偶数
奇数,偶数--------------->操作后变成 奇数,奇数
偶数,奇数--------------->操作后变成 奇数,奇数
偶数,偶数--------------->操作后变成 偶数,偶数
所以:
如果原来两个数都是偶数的话,那么操作数为0.
如果原来两个数都是奇数的话,那么操作数为1.
如果原来两个数是一奇一偶的话,那么操作数为2.
其一定不会出现结果是(3 ,6)这种情况的,除非原序列就是这样的。
所以,最后再加几个特判即可:
如果n == 1,其gcd一定是1,所以直接输出即可;
如果gcd在不操作之前已经大于1了,直接输出即可;
其他情况再讨论奇偶性即可...(注意这道题不存在无解的情况,前面已经解释过)....
AC代码:
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
1 #include<iostream> 2 #include<cstdio> 3 4 using namespace std; 5 6 int n, a[100005], ans; 7 8 int gcd(int a, int b){ 9 if(b == 0) 10 return a; 11 return gcd(b, a % b); 12 } 13 14 int main(){ 15 scanf("%d", &n); 16 for(int i = 1; i <= n; i++) 17 scanf("%d", &a[i]); 18 if(n == 1){ 19 printf("YES\n0\n"); 20 return 0; 21 }//特判 22 int now = gcd(a[1], a[2]); 23 for(int i = 3; i <= n; i++) 24 now = gcd(a[i], now);//gcd 25 if(now != 1){ 26 printf("YES\n0\n"); 27 return 0; 28 }//特判 29 else{ 30 a[n + 1] = 0; 31 for(int i = 1; i <= n; i++){ 32 if(a[i] % 2 == 1 && a[i + 1] % 2 == 1){ 33 ans++; 34 a[i + 1] = 0;//已经操作成偶数,所以赋值成任何一个偶数都可 35 } 36 else if(a[i] % 2 == 1 && a[i + 1] % 2 == 0)//一奇一偶 37 ans += 2; 38 } 39 printf("YES\n%d\n", ans); 40 } 41 return 0; 42 }