G. Greatest Common Divisor ###K //K

题目链接:https://codeforces.ml/gym/102823/problem/G

题意:每次操作使得整个区间+1 问最少多少次 使得整个区间的gcd大于1 如果不存在输出-1
思路:根据gcd的差分性质  转换成差分数组 即每次只能是a[1]++ 那么就是2~n的gcd d 要多少次才能变成大于1

设 d= 2~n 的gcd  (差分后)  然后记得把d取绝对值(因为d可能为负数的gcd)  特判一下d==1 无解  d==0 的时候看 a[1]的值 为1就是1 否则为0

然后 枚举d的因子, 找 a[1] 至少加多少能达到因子的倍数 取一个min值即可

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 const int maxn=1e5+10;
 4 const int mod=1e9+7;
 5 #define ll long long
 6 #define ull unsigned long long
 7 #define pi pair<int,ll>
 8 #define fi first
 9 #define sc second
10 #define pb push_back
11 int a[maxn];
12 
13 int gcd(int a,int b)
14 {
15     if(b==0) return a;
16     return gcd(b,a%b);
17 }
18 
19 
20 int main()
21 {
22     ios::sync_with_stdio(0);
23     cin.tie(0);
24     int t;
25     cin>>t;
26     int c=0;
27     while(t--)
28     {
29         int n;
30         cin>>n;
31         for(int i=1;i<=n;i++) cin>>a[i];
32         for(int i=n;i>=1;i--) a[i]-=a[i-1];
33         int x=0;
34         for(int i=2;i<=n;i++) x=gcd(x,a[i]);
35         x=abs(x);
36         int ans=1e9;
37         if(x==0)
38         {
39             if(a[1]==1) ans=1;
40             else ans=0;
41             cout<<"Case "<<++c<<": "<<ans<<'\n';
42             continue;
43         }
44         if(x==1)
45         {
46             ans=-1;
47             cout<<"Case "<<++c<<": "<<ans<<'\n';
48             continue;
49         }
50         for(int i=1;i*i<=x;i++)
51         {
52             if(x%i!=0) continue;
53             int q=i;
54             if(q!=1)
55             {
56                 ans=min(ans,(q-a[1]%q)%q);
57             }
58             q=x/i;
59             ans=min(ans,(q-a[1]%q)%q);
60         }
61         cout<<"Case "<<++c<<": "<<ans<<'\n';
62 
63 
64 
65 
66 
67     }
68 
69 
70 
71 }
View Code

 

posted @ 2020-12-07 22:48  canwinfor  阅读(89)  评论(0)    收藏  举报