Educational Codeforces Round 57 (Rated for Div. 2) 小结 A,B,C

Educational Codeforces Round 57 (Rated for Div. 2) 小结 A,B,C

前言:

好几天没写博客了,先反省一下,然后codeforces 529打的很不好,还在补题,有时间应该会把博客补起来 ( 假的,最近cf超级多
这一场应该算是数学场吧,前三题思路清晰的话还是很快的,第四题个人觉得是DP,反正想了很久都没有办法,后面的三个题真的也是数学题的样子,但是奈何博主太弱,只能看出来大概是用逆元求期望orz。
言归正传,还是记录一下答题流程好了,按照博主一罐一贯的风格,21分钟比赛就结束了(雾),3min出的A,实话说有点慢,在一些细节的处理上浪费了点时间,10min 出B,还行,然后 21min 出的C,C WA一了(雾),不算罚时,所以相当于都是一A,就这样。

A. Find Divisible

题意
就是给定一段数字,从中选取出两个不同但是前一个是后一个因数的两个数
做法
题面里面保证了一定存在整除关系,那么我们不妨考虑最小的,因为,如果存在三倍,那么一定存在两倍,并且,如果该数不是左端的数,那么左端的数的两倍也一定存在,综上,不难得出,我们只需要输出左端的数和他的两倍就好了。
代码

#include 
using namespace std;
int main()
{
    int t;
    scanf("%d",&t);
    while(t--)
    {
        int n,l;
        scanf("%d%d",&n,&l);
        printf("%d %d\n",n,n*2);
    }
}

B. Substring Removal

题意
给定一个字符串,要求删掉一段连续的,得到一串所有字符相同的或者是空串,问,有多少种删除的方法。
做法
不难看出,最后剩下的只有四种可能,一,空串,二,前缀,三,后缀,四,前缀加后缀。
因此,我们考虑满足条件的前缀的长度qian和满足条件的后缀的长度hou。
如果前缀和后缀所用的元素相同,则我们考虑中间剩余的部分,他可以从前缀中选取一部分或不选,共有(qian+1)种可能,同理,后缀是(hou+1)种,所以输出(qian+1)*(hou+1)。
如果前缀后后缀所用的元素不相同,则前缀和后缀必然有一部分要被完全删去,则应该是上面两种情况的加和,即(qian+hou+2)但是,考虑到两种情况都会出现空串,所以最后的答案是(qian+hou+1)。
做法

#include 
#define mod 998244353
using namespace std;
char a[200020];
int main()
{
    int n;
    scanf("%d",&n);
    scanf("%s",a);
    long long qian =1;
    long long hou = 1;
    int i = 1;
    while(a[i]==a[0])
    {
        qian++;
        i++;
    }
    i = n-2;
    while(a[i]==a[n-1])
    {
        hou++;
        i--;
    }
    if(a[0]!=a[n-1])
    {
        printf("%lld\n",(qian+hou+1)%mod);
    }
    else
    {
        printf("%lld\n",(qian+1)*(hou+1)%mod);
    }
}


注意
为了防止两个数相乘爆int,一定要用longlong!!!之前比赛血的教训。

C. Polygon for the Angle

题意
给定一个角度,问包含该角度的边数最少的正多边形的变数。
例题配的图,输入54,输出10.
Educational Codeforces Round 57 (Rated for Div. 2) 小结 A,B,C_第1张图片
做法
我们都知道正n边形的每个内角为180*(n-2)/n,并且它的顶点均匀地分布在圆周上。对于任意一个角,除了组成他的两条边以外,剩下的(n-2)条边均匀地分割它,及我们从剩下的(n-3)个顶点分别向这个角的顶点做线,可以得到(n-2)个相等的角,每一个角的度数为180*(n-2)/n。而我们能够得到的角度一定是这些角的组合,因此,我们只要考虑这个被分成(n-2)的角,是不是能够整除我们给定的角就好了。以图中的54为例,即,我们要求在k为正整数的情况下,满足(180/n)*k=54的最小正整数n。
变形该式可得n=(180*k)/54由于给定角的范围小于180度,不妨遍历(笑),但是我们也可以用数学方法进行推导,要使得上式中的n尽可能小,则k尽可能小,即180要尽量分担54带来的影响,所有我们求一下gcd然后剩下的需要k承担的只剩下54/gcd,然后可以得出n的值。
注意
由于存在如给定角大于最后正n边形角的可能,所以一旦出现,我们就将原先得到的答案乘以二,一次来避免诸如178,135,179这样的特殊角。
代码

#include 
#include 
using namespace std;
int main()
{
    int t;
    scanf("%d",&t);
    while(t--)
    {
        int n;
        scanf("%d",&n);
        int tmp = __gcd(180,n);
        int k = n/tmp;
        int ans = 180*k/n;
        if(180*(ans-2)/ans

后话

看了下大佬们的D,果然是DP,很巧妙的那种,看来还要加紧训练才行,毕竟不是每次都是数学场。

你可能感兴趣的:(codeforces)