Codeforces Round #579 (Div. 3)

30 篇文章 0 订阅
25 篇文章 0 订阅

回归之旅,怎么能少了cf,从div3开始玩起,又是一年多没玩的游戏了,赶紧上手找找感觉,题目不难,最重要的就是自信与时间的把握,确实太久没做题了

A. Circle of Students

思路:简单判循环题,正反两下循环即可搞定,手太生了,连循环都不敢写了

#include <bits/stdc++.h>

using namespace std;

#define ne ((i+1)%n)
#define la ((i+n-1)%n)

const int maxn = 210;

int a[maxn];

int main()
{
    int q;
    scanf("%d",&q);
    while(q--)
    {
        int n;
        scanf("%d",&n);
        int st = -1;
        for(int i=0;i<n;i++)
        {
            scanf("%d",&a[i]);
            if(a[i]==1)
            {
                st = i;
            }
        }
        //cout << st <<endl;
        if(st == -1)    printf("NO\n");
        else if(n==1)   printf("YES\n");
        else
        {
            if(a[((st+1)%n)]==2)
            {
                bool ok = true;
                for(int i=st;ok&&(i!=((st+n-1)%n));i=ne)
                {
                    //cout << i << "@" << ne << "@" << a[i] << "@" << a[ne] << endl;
                    if(a[i]!=a[ne]-1)   ok = false;
                }
                if(ok)  printf("YES\n");
                else    printf("NO\n");
            }
            else if(a[((st+n-1)%n)]==2)
            {
                bool ok = true;
                for(int i=st;ok&&(i!=((st+1)%n));i=la)
                {
                    if(a[i]!=a[la]-1)   ok = false;
                }
                if(ok)  printf("YES\n");
                else    printf("NO\n");
            }
            else    printf("NO\n");
        }
    }
    return 0;
}

B. Equal Rectangles

思路:给定特定边,判断能否组成n个面积相等的矩形,由于面积乘法公式的单调性,直接暴力开乘,注意一下边界即可

#include <bits/stdc++.h>

using namespace std;

const int maxn = 1100;

int a[maxn];

int main()
{
    int q;
    scanf("%d",&q);
    while(q--)
    {
        int n;
        scanf("%d",&n);
        for(int i=0;i<4*n;i++)    scanf("%d",&a[i]);
        sort(a,a+4*n);
        int st = 0;
        int en = 4*n-1;
        bool ok = true;
        if(a[st+1]!=a[st]||a[en-1]!=a[en])  ok = false;
        int sq = a[st] * a[en];
        for(st+=2,en-=2;ok&&st<en;st+=2,en-=2)
        {
            if(a[st+1]!=a[st]||a[en-1]!=a[en])  ok = false;
            if(sq != a[st] * a[en]) ok = false;
        }
        if(ok)  printf("YES\n");
        else    printf("NO\n");
    }
    return 0;
}

C. Common Divisors

思路:求n个数的公因数个数,如此水题居然把我困住了,公因数个数先求最大公因数,然后将最大公因数分解即可。还是手太生疏了

#include <bits/stdc++.h>

using namespace std;

int countfactor(long long n)
{
    int sum=1;
    for(long long i=2;i<=(long long)(sqrt(double(n))+1LL);i++)
    {
        int cnt=0;
        while(n%i==0)
        {
            n/=i;
            cnt++;
        }
        sum*=(cnt+1);
    }
    if(n>1LL)
        sum*=2;
    return sum;
}


int main()
{
    int n;
    long long a;
    long long res;
    scanf("%d",&n);
    scanf("%I64d",&res);
    for(int i=1;i<n;i++)
    {
        scanf("%I64d",&a);
        res = __gcd(res,a);
    }
    printf("%d\n",countfactor(res));
    return 0;
}

D2. Remove the Substring (hard version)

思路:D1简单版我就跳过了,hard版过简单版。

在保证匹配的情况下,求母串可删的最长长度

这就是个字符串双扫描问题,第一次扫描将子串与母串映射,由于第二次扫描具有单调性,实现起来完全ok,最后考虑一下两端边界就ok了。其实现在最大的问题就是自己内心的惧怕,看似很复杂,其实并不会很难,而在于自己内心的自信以及对时间的把握上

#include <bits/stdc++.h>

using namespace std;

const int maxn = 2e5+10;
char s[maxn];
char t[maxn];
int pos[maxn];

int main()
{
    scanf("%s%s",s,t);
    int sl = strlen(s), tl = strlen(t);
    int nowpos = 0;
    int i;
    for(i=0;i<sl;i++)
    {
        if(t[nowpos]==s[i])
        {
            pos[nowpos]=i;
            nowpos++;
            if(nowpos == tl)    break;
        }
    }
    int re = sl - i - 1;
    nowpos = tl-1;
    for(i=sl-1;i>0;i--)
    {
        if(t[nowpos]==s[i])
        {
            nowpos--;
            re = max(re,i-pos[nowpos]-1);
            //cout << pos[nowpos] << "*" << i << "*" << re << endl;
            if(nowpos == -1) break;
        }
    }
    re = max(re,i);
    printf("%d\n",re);
    return 0;
}

E. Boxers

思路:每个元素最多可变化1,求集合最大互异元素数量,于是排序,之后枚举3种情况统计即可

#include <bits/stdc++.h>

using namespace std;

const int maxn = 2e5;
int a[maxn];

int main()
{
    int n;
    scanf("%d",&n);
    int sum = 0;
    for(int i=0;i<n;i++)
    {
        scanf("%d",&a[i]);
    }
    sort(a,a+n);
    int pos = 0;
    for(int i=0;i<n;i++)
    {
        if(a[i]-1>pos)
        {
            sum++;
            pos = a[i]-1;
        }
        else if(a[i]>pos)
        {
            sum++;
            pos = a[i];
        }
        else if(a[i]+1>pos)
        {
            sum++;
            pos = a[i]+1;
        }
    }
    printf("%d\n",sum);
    return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值