CF798 C. Mike and gcd problem

 1 /*
 2  CF798 C. Mike and gcd problem
 3  http://codeforces.com/contest/798/problem/C
 4  数论 贪心
 5  题意:如果一个数列的gcd值大于1,则称之为美丽数列
 6     给出数列a,可以将a_i 和 a_(i+1)换为其差和其和
 7     如果可以变为美丽数列,输出YES并输出最少的变换次数
 8     否则输出NO
 9  思路:
10     如果变换a b
11     a b -> a-b a+b -> -2b 2a
12     因此变换两个可以把a b乘以2
13     而若a b都是奇数,只需变换一次
14     所以每次先找出相邻是奇数的情况ans++
15     然后找相邻是奇偶的情况ans+=2
16  然而
17     比赛的时候居然把ans=gcd(ans,num[i]) 写成了ans=gcd(ans,i)
18     这居然还过了40组数据,也是醉了,雪崩!
19  */
20 
21 #include <cstdio>
22 #include <algorithm>
23 #include <cstring>
24 #include <cmath>
25 #include <vector>
26 #include <queue>
27 #include <iostream>
28 #include <map>
29 #include <set>
30 //#define test
31 using namespace std;
32 const int Nmax=1e6+7;
33 int n;
34 long long num[Nmax];
35 long long gcd(long long a,long long b)
36 {
37     if(b==0)
38         return abs(a);
39     return gcd(b,a%b);
40 }
41 int main()
42 {
43     #ifdef test
44     #endif
45     scanf("%d",&n);
46     for(int i=1;i<=n;i++)
47         scanf("%I64d",&num[i]);
48     long long ans=0LL;//初始化一定要看仔细
49     for(int i=1;i<=n;i++)
50     {
51         ans=gcd(ans,num[i]);//num[i]一定不要写成i!!!!!
52     }
53     if(ans>1)
54     {
55         printf("YES\n0\n");
56         return 0;
57     }
58     ans=0LL;
59     for(int i=1;i<n;i++)
60     {
61         if((num[i]&1) && (num[i+1]&1))
62         {
63             ans++;
64             num[i]=2;
65             num[i+1]=2;
66         }
67     }
68     for(int i=1;i<=n;i++)
69     {
70         if(num[i]&1)
71         {
72             ans+=2;
73         }
74     }
75     printf("YES\n%I64d\n",ans);
76     return 0;
77 }

 

posted @ 2017-04-22 02:29  BBBob  阅读(2187)  评论(0编辑  收藏  举报