1. 程式人生 > >coderforces Educational Codeforces Round 57 A-D

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

我們知道正多邊形 外接一個圓 所以同弦的圓周角相同 也就是說 內角和為 (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;
}