【Codeforces Round #446 (Div. 2) C】Pride

【链接】 我是链接,点我呀:)
【题意】

在这里输入题意

【题解】

想一下,感觉最后的结果肯定是从某一段开始,这一段的gcd为1,然后向左和向右扩散的。
则枚举那一段在哪个地方。
我们设这一段中所有的数字都做了一次gcd.

假设在i..j这一段。
则求gcd的顺序是(i,i+1),(i+1,i+2)...(j-1,j)
这样a[j]=gcd(a[i],a[i+1]..a[j])了

即顺序求了一遍gcd.
这样,预处理一下i到j的gcd.
如果gcd[i][j]==1,则获取到一个可行方案。
求一下次数的最小值就好了
即(j-i)*2 + i-1 + n-j

当然,如果已经有1了,就没必要去凑一个1出来了。
直接枚举从1开始向左、向右就好。

【代码】

#include <bits/stdc++.h>
using namespace std;

const int N = 2e3;
int a[N+10],n;
int f[N+10][N+10];

int main(){
    #ifdef LOCAL_DEFINE
        freopen("F:\\c++source\\rush_in.txt", "r", stdin);
    #endif
    scanf("%d",&n);
    for (int i = 1;i <= n;i++) scanf("%d",&a[i]);
    int ans = -1;

    //have 1
    for (int i = 1;i <= n;i++)
        if (a[i]==1){
            int cnt = 0;
            for (int j = i-1;j >= 1;j--)
                if (a[j]!=1){
                    cnt++;
                }
            for (int j = i+1;j <= n;j++)
                if (a[j]!=1){
                    cnt++;
                }
            if (ans==-1 || ans > cnt) ans = cnt;
        }

    int temp = a[1];
    for (int i = 2;i <=n;i++) {
        temp = __gcd(temp,a[i]);
    }
    if (temp!=1){
        puts("-1");
        return 0;
    }
    for (int i = 1;i <= n;i++){
        f[i][i] = a[i];
        for (int j = i+1;j <= n;j++){
            f[i][j] = __gcd(f[i][j-1],a[j]);
        }
    }
    for (int i = 1;i <= n;i++){
        for (int j = i;j <= n;j++)
            if (f[i][j]==1){
                 int temp = (j-i)*2 + (i-1) + (n-j);
                 if (ans==-1){
                    ans = temp;
                 }else ans = min(ans,temp);
            }
    }
    printf("%d\n",ans);
    return 0;
}
时间: 2024-08-30 02:13:59

【Codeforces Round #446 (Div. 2) C】Pride的相关文章

【Codeforces Round #446 (Div. 2) A】Greed

[链接] 我是链接,点我呀:) [题意] 在这里输入题意 [题解] 贪心选容量大的瓶子就好 [代码] #include <bits/stdc++.h> #define int long long using namespace std; const int N = 1e5; int n; int a[N+10],b[N+10]; main(){ #ifdef LOCAL_DEFINE freopen("F:\\c++source\\rush_in.txt", "r

【Codeforces Round #447 (Div. 2) A】QAQ

[链接] 我是链接,点我呀:) [题意] 在这里输入题意 [题解] C语言程序练习题 [代码] #include <bits/stdc++.h> using namespace std; string s; int main(){ #ifdef LOCAL_DEFINE freopen("F:\\c++source\\rush_in.txt", "r", stdin); #endif ios::sync_with_stdio(0),cin.tie(0);

【Codeforces Round #451 (Div. 2) D】Alarm Clock

[链接] 我是链接,点我呀:) [题意] 在这里输入题意 [题解] 尺取法+二分. 类似滑动窗口. 即左端点为l,右端点为r. 维护a[r]-a[l]+1总是小于等于m的就好. (大于m就右移左端点) 然后看看里面的数字个数是不是小于k; 不是的话让l..r中最右边那个数字删掉就好. ->链表优化一下即可. [代码] /* 1.Shoud it use long long ? 2.Have you ever test several sample(at least therr) yourself

【Codeforces Round #452 (Div. 2) A】 Splitting in Teams

[链接] 我是链接,点我呀:) [题意] 在这里输入题意 [题解] 贪心 1优先和2组队. 如果1没有了 就结束. 如果1还有多余的. 那么就自己3个3个组队 [代码] #include <bits/stdc++.h> using namespace std; const int N = 2e5; int n; int a[3]; int main(){ #ifdef LOCAL_DEFINE freopen("rush_in.txt", "r", st

【Codeforces Round #452 (Div. 2) B】Months and Years

[链接] 我是链接,点我呀:) [题意] 在这里输入题意 [题解] 闰,平,平 平,闰,平 平,平,闰 平,平,平 4种情况都考虑到就好. 可能有重复的情况. 但是没关系啦. [代码] #include <bits/stdc++.h> using namespace std; const int N = 24; int p[12] = {31,28,31,30,31,30,31,31,30,31,30,31}; int r[12] = {31,29,31,30,31,30,31,31,30,3

【Codeforces Round #452 (Div. 2) C】 Dividing the numbers

[链接] 我是链接,点我呀:) [题意] 在这里输入题意 [题解] n为偶数. l = 1, r = n (l,r)放在一组 l++,r-- 新的l,r放在另外一组 直到l+1==r 这个时候,判断两组的和,如果一样的话,分散在两组 差为1否则差为0 n为奇数 l = 2,r = n (l,r)放在一组 l++,r-- 新的l,r放在另外一组 直到l+1==r 这个时候,判断两组的和,如果一样的话,分散在两组 差为0(把1放在那个较少的组) 否则,差为1 1随意放在哪一组都可以 [代码] #in

【Codeforces Round #456 (Div. 2) C】Perun, Ult!

[链接] 我是链接,点我呀:) [题意] 在这里输入题意 [题解] set1 < pair < int,int > > set1;记录关键点->某个人怪物永远打不死了,第一维是时间,第二维是下标 int dic[1e5+10] //记录对应下标的怪物它此时此刻在何时打不死了 set2 < pair< int,int > > set2;关键点2->有怪物要更新了的时间点,以及记录的信息下标idx2 之所以这样记录.是为了尽可能多地让怪物存活时间长一

【Codeforces Round #457 (Div. 2) A】 Jamie and Alarm Snooze

[链接] 我是链接,点我呀:) [题意] 在这里输入题意 [题解] 暴力往前走x分钟就好. 直到出现7为止. [代码] #include <bits/stdc++.h> using namespace std; int hh,mm,x,cnt; bool find7(){ if (hh%10==7 || (hh/10)==7) return true; if (mm%10==7 || (mm/10)==7) return true; return false; } int main(){ #i

【Codeforces Round #457 (Div. 2) B】Jamie and Binary Sequence

[链接] 我是链接,点我呀:) [题意] 在这里输入题意 [题解] 把n分解成二进制的形式. n=2^a0+2^a1+...+2^a[q-1] 则固定就是长度为q的序列. 要想扩展为长为k的序列. 可以把2^x转化为2^(x-1)+2^(x-1)的形式. 这样序列的长度就+1了 它要求max{ai}最大 那么我们可以枚举ai的最大值是什么->i (递减着枚举) 然后比i大的ai都换成两个ai-1的形式. 然后看看序列的长度是否小于等于k; 如果小于k的话. 就把min{ai}分解成两个min{a