coderforces Educational Codeforces Round 57 A-D

在寝室睡了几天以后过来做 自闭了

A题

题意 给你t组样例 一个区间 l 到 r ,让你输出 l 到 r 内一对其中一个是另一个的因子的答案 , 保证题目有解

于是我们直接输出左端点 和左端点乘2 即可 保证是最小的答案

#include <cstdio>
#include <queue>
#include <cmath>
#include <cstring>
#include <iostream>
#include <stack>
#include <set>
#include <sstream>
#include <vector>
#include <algorithm>
using namespace std;
#define dbg(x) cout<<#x<<" = "<< (x)<< endl

int main()
{
    int t;
    scanf("%d",&t);
    while(t--)
    {
        long long a,b;
        scanf("%lld%lld",&a,&b);
        printf("%lld %lld\n",a,a*2);
    }

    return 0;
}



B题

题意 给你一个长度为n的字符串 你可以删掉任意长度的子串(包括n) 使得剩下的串都是同一个字符 或者 没有字符(删掉n)

我们可以分类讨论一下会发现几种类型的删除方法

abaa 和 abcc 和 aaaa

可以模拟一下 就可以写了

#include <cstdio>
#include <queue>
#include <cmath>
#include <cstring>
#include <iostream>
#include <stack>
#include <set>
#include <sstream>
#include <vector>
#include <algorithm>
using namespace std;
#define dbg(x) cout<<#x<<" = "<< (x)<< endl
#define MOD 998244353
char str[200025];

int main()
{
    bool flag = false;
    long long n,tmp = 1,tmp_,len = 1,ans = 0;
    scanf("%lld",&n);
    tmp_ = n;
    scanf("%s",str+1);
    if(str[n]==str[1]) flag = true;
    while(str[tmp]==str[tmp+1]&&tmp<n)
    {
        tmp++;
    }
    while(str[tmp_]==str[tmp_-1]&&tmp_>1)
    {
        tmp_--;
        len++;
    }
    if(tmp==n)
    {
            printf("%lld\n",(n*(n+1)/2)%MOD);
            return 0;
    }
    if(flag)
    {
        while(tmp--)
        {
            ans+=len+1;
        }
        ans+=len+1;
        printf("%lld\n",ans%MOD);
    }
    else printf("%lld\n",(len+tmp+1)%MOD);
    return 0;
}



C题

题意 给你 t 组样例,问你每个样例的角度可以由 正x边形凑成 输出最小的x

扫描二维码关注公众号,回复: 4698251 查看本文章

我们知道正多边形 外接一个圆 所以同弦的圆周角相同 也就是说 内角和为 (x-2)*180 ,每个内角为 (x-2)*180 / x,每个内角可以等分(x-2)段 即小单元为 180/x 

于是就可以模拟了 可以用乘法代替出发 也可以直接用fmod

#include <cstdio>
#include <queue>
#include <cmath>
#include <cstring>
#include <iostream>
#include <stack>
#include <set>
#include <sstream>
#include <vector>
#include <algorithm>
using namespace std;
#define dbg(x) cout<<#x<<" = "<< (x)<< endl
vector <pair<double ,int > > arr;
int main()
{
    int t;
    scanf("%d",&t);
    for(int i = 3;i<=15500;i++)
    {
            arr.push_back(make_pair(1.0*180/i,i));
    }
    while(t--)
    {
        int n;
        scanf("%d",&n);
        /*if(n&1)
        {
            printf("-1\n");
            continue;
        }*/
        int sz = arr.size();
        int flag = 0;
        for(int i = 0;i<sz;++i)
        {

            if(fmod(1.0*n,arr[i].first)==0&&((arr[i].second-2)*arr[i].first>=n))
            {
                flag = 1;
                printf("%d\n",arr[i].second);
                break;
            }
        }
        if(!flag) printf("-1\n");
    }
    return 0;
}


D题

题意 我们定义一个串里面如果按顺序出现 h a r d 那么就是h a r d 串 要求你删除任意字符 使得不存在h a r d 串

做法:我们知道要是不想要hard 就可以删除掉 h 使得 hard不存在 ,或者删除掉ha使得hard不存在,或者删除掉har使得hard不存在 或者删除掉hard使得hard不存在

我们知道 当一个最小的删除h使得hard不存在 可能要删除多个h 但是删除a的时候可以由之前删除了一个h再删除一个a即可 不需要多次删除

所以我们定义一个四个状态的dp fa[0][i]代表 i 长度前面的h都被删除需要的代价 同理 dp[1][i]代表 i 长度前面的ha都被删除所需要的代价,dp[2][i] 代表 i 长度前面的har 都被删除所需要的代价 , dp[3][i] 代表 i 长度前面的hard 都被删除所需要的代价

#include <cstdio>
#include <queue>
#include <cmath>
#include <cstring>
#include <iostream>
#include <stack>
#include <set>
#include <sstream>
#include <vector>
#include <algorithm>
using namespace std;
#define dbg(x) cout<<#x<<" = "<< (x)<< endl
#define MOD 998244353
const int MAX_N = 100025;
long long fa[4][MAX_N],a[MAX_N];
char str[MAX_N];
int main()
{
    int n;
    scanf("%d",&n);
    scanf("%s",str+1);
    for(int i = 1;i<=n;++i) scanf("%lld",&a[i]);
    for(int i = 1;i<=n;++i)
    {
        fa[0][i] = fa[0][i-1]+a[i]*(str[i]=='h');
        fa[1][i] = min(fa[0][i],fa[1][i-1]+a[i]*(str[i]=='a'));
        fa[2][i] = min(fa[1][i],fa[2][i-1]+a[i]*(str[i]=='r'));
        fa[3][i] = min(fa[2][i],fa[3][i-1]+a[i]*(str[i]=='d'));
    }
    printf("%lld\n",min(min(fa[0][n],fa[1][n]),min(fa[2][n],fa[3][n])));
    return 0;
}



猜你喜欢

转载自blog.csdn.net/heucodesong/article/details/85336798
今日推荐