码迷,mamicode.com
首页 > 其他好文 > 详细

Codeforces Round #655 题解

时间:2020-07-26 00:22:51      阅读:52      评论:0      收藏:0      [点我收藏+]

标签:两个指针   ace   href   指针   clu   ret   int   name   tps   

https://codeforces.com/contest/1372

A

众所周知,\(1+1\neq 1\)

所以输出 \(n\)\(1\) 即可。

时间复杂度 \(O(tn)\)

#include <bits/stdc++.h>
using namespace std;
int t;
int n;
int main() {
    scanf("%d",&t);
    while(t--) {
        scanf("%d",&n);
        for(int i=1;i<=n;i++)
            printf("1 ");
        puts("");
    }
    return 0;
}

B

\(x\)\(n\) 最小的质因数。

此时答案为 \(\frac{n}{x},n-\frac{n}{x}\)

于是可以 \(O(\sqrt{n})\) 解决每组数据。

#include <bits/stdc++.h>
using namespace std;
int t;
int n,fl;
int main() {
    scanf("%d",&t);
    while(t--) {
        scanf("%d",&n);
        fl=1;
        for(int i=2;i*i<=n;i++)
            if(n%i==0) {
                printf("%d %d\n",n/i,n-n/i);
                fl=0;
                break;
            }
        if(fl)
            printf("%d %d\n",1,n-1);
    }
    return 0;
}

C

考虑将每个数按在不在自己的位置归类。

找到所有不在自己的位置的段的个数即可。

于是您就 WA 了。

如果有若干段不在自己的位置的段的话,可以考虑把所有位置全部打乱,再一一对应。

时间复杂度:\(O(tn)\)

#include <bits/stdc++.h>
using namespace std;
int t;
int n,a[200010],fl;
long long ans;
int main() {
    scanf("%d",&t);
    while(t--) {
        scanf("%d",&n);
        ans=0;
        for(int i=1;i<=n;i++)
            scanf("%d",&a[i]);
        for(int i=2;i<=n;i++)
            if(a[i]==i&&a[i-1]!=i-1)
                ans++;
        if(a[n]!=n)
            ans++;
        if(ans>2)
            ans=2;
        printf("%d\n",ans);
    }
    return 0;
}

D

这个出题人我点个赞!

看到环形,就能想到破环为链,先破掉。

然后呢?

找规律 txdy!

捏组样例看看:

1 2 3 4 5 6 7
(2+7) 3 4 5 6 // 对 1 处进行操作
3 4 (5+2+7) // 对 6 处进行操作
3+5+2+7 //对 4 处进行操作

考虑对答案的贡献的数,似乎没规律的样子。

可是一条链的视角来看呢?

1 2 (3) 4 (5) 6 (7) 1 (2) 3 4 5 6 7

可以猜测,对于任意的环而言,均有这样的规律。

所以,我们可以求出下标均为奇数,长度为 \(\frac{n+1}{2}\) 的连续子序列。

对偶数也一样。

求连续子序列的和可以使用 \(l,r\) 两个指针。

时间复杂度 \(O(n)\)

#include <bits/stdc++.h>
using namespace std;
int t,l,r;
int n,a[400010],k;
long long ans,sum;
int main() {
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
        scanf("%d",&a[i]);
    for(int i=1;i<=n;i++)
        a[i+n]=a[i];
    k=(n+1)/2-1;
    l=1,r=l+k*2;
    for(int i=l;i<=r;i+=2)
        sum+=a[i];
    ans=max(ans,sum);
    while(r<=2*n) {
        l+=2,r+=2;
        sum-=a[l-2];
        sum+=a[r];
        ans=max(ans,sum);
    }
    l=2,r=l+k*2;
    sum=0;
    for(int i=l;i<=r;i+=2)
        sum+=a[i];
    ans=max(ans,sum);
    while(r<=2*n) {
        l+=2,r+=2;
        sum-=a[l-2];
        sum+=a[r];
        ans=max(ans,sum);
    }
    printf("%lld\n",ans);
    return 0;
}

Codeforces Round #655 题解

标签:两个指针   ace   href   指针   clu   ret   int   name   tps   

原文地址:https://www.cnblogs.com/lajiccf/p/CF655.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!