Educational Codeforces Round 103 (Rated for Div. 2)爆炸记

A

这题WA了2次,出师不利。n>k的情况很特殊,若n%k==0答案是1,否则是2,n<=k时,答案是k/n上取整

#include<bits/stdc++.h>
using namespace std;
int main()
{
    int T,n,k,rest;scanf("%d",&T);
    while(T--)
    {
        scanf("%d%d",&n,&k);
        if(n%k==0)puts("1");
        else if(n>k)puts("2");
        else printf("%d
",(k-1)/n+1);
    }
}
View Code

B

容易发现修改数据只需加在第一个数就行,然后循环枚举一遍x/sum<=k/100,移项得sum>=100x/k,每个位置找最大值

#include<bits/stdc++.h>
using namespace std;
int T,n,k;
long long ans,s,x;
int main()
{
    scanf("%d",&T);
    while(T--)
    {
        scanf("%d%d",&n,&k);
        s=ans=0;
        for(int i=1;i<=n;i++)
        {
            scanf("%lld",&x);
            if(i>1)ans=max(ans,(100*x-1)/k+1-s);
            s+=x;
        }
        printf("%lld
",ans);
    }
}
View Code

C

从后往前模拟,若出现首尾连接在一起则直接统计答案,重新开始计算,否则可以手算出带上当前位置后答案的改变,若小于链长则替换为链长

#include<bits/stdc++.h>
using namespace std;
const int N=1e5+7;
int T,n,c[N],a[N],b[N];
long long ans,sum;
int main()
{
    scanf("%d",&T);
    while(T--)
    {
        scanf("%d",&n);
        for(int i=1;i<=n;i++)scanf("%d",&c[i]);
        for(int i=1;i<=n;i++)scanf("%d",&a[i]);
        for(int i=1;i<=n;i++)scanf("%d",&b[i]);
        ans=0,sum=c[n]-1;
        for(int i=n;i>1;i--)
        if(a[i]==b[i])ans=max(ans,sum+2),sum=c[i-1]-1;
        else{
            int u=min(a[i],b[i]),v=max(a[i],b[i]);
            ans=max(ans,sum+2+v-u);
            sum=max(sum+1+c[i-1]-v+u,c[i-1]-1ll);
        }
        printf("%lld
",ans);
    }
}
View Code

D

裸DP,l/r[i][0/1]表示变换了0/1次后向左/右最长能走多少距离,直接推状态即可

#include<bits/stdc++.h>
using namespace std;
const int N=3e5+7;
int n,l[N][2],r[N][2];
char a[N];
int main()
{
    int T;scanf("%d",&T);
    while(T--)
    {
        scanf("%d",&n);
        scanf("%s",a+1);
        l[0][0]=l[0][1]=0;
        for(int i=1;i<=n;i++)
        {
            if(a[i]=='L')l[i][1]=0,l[i][0]=l[i-1][1]+1;
            else l[i][0]=0,l[i][1]=l[i-1][0]+1;
        }
        r[n][0]=r[n][1]=0;
        for(int i=n-1;~i;i--)
        {
            if(a[i+1]=='R')r[i][1]=0,r[i][0]=r[i+1][1]+1;
            else r[i][0]=0,r[i][1]=r[i+1][0]+1;
        }
        for(int i=0;i<=n;i++)printf("%d ",l[i][0]+r[i][0]+1);
        puts("");
    }
}
View Code

E

555看错题了,实际上很水,对每个串枚举变为_的位置然后建边,此时就排除掉一些不符合的情况,然后就是裸的拓扑排序了

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=2e5+7;
int n,m,d,mt,cnt,sid[150],ans[N],deg[N];
string t,s[N];
map<int,int>pos;
vector<int>G[N];
int calc(string s)
{
    int ret=0;
    for(int i=0;i<s.size();i++)ret=ret*28+sid[s[i]];
    return ret;
}
int main()
{
    for(int i=0;i<26;i++)sid[i+'a']=i;sid['_']=27;
    cin>>n>>m>>d;
    for(int i=1;i<=n;i++)cin>>s[i];
    for(int i=1;i<=n;i++)pos[calc(s[i])]=i;
    for(int i=1;i<=m;i++)
    {
        cin>>t;scanf("%d",&mt);
        bool has=0;
        for(int S=0;S<(1<<d);S++)
        {
            string tt=t;
            for(int j=0;j<t.size();j++)if((S>>j)&1)tt[j]='_';
            int val=calc(tt);
            if(pos.find(val)!=pos.end())
            {
                if(pos[val]==mt)has=1;
                else G[mt].push_back(pos[val]),deg[pos[val]]++;
            }
        }
        if(!has){puts("NO");return 0;}
    }
    queue<int>q;
    for(int i=1;i<=n;i++)if(!deg[i])q.push(i);
    while(q.size())
    {
        int u=q.front();q.pop();
        ans[++cnt]=u;
        for(int i=0;i<G[u].size();i++)if(!(--deg[G[u][i]]))q.push(G[u][i]);
    }
    if(cnt<n)puts("NO");
    else{
        puts("YES");
        for(int i=1;i<=n;i++)printf("%d ",ans[i]);
    }
}
View Code

WA了2发A+看错E题目=排名很烂,rank=249 rating+=160

相关推荐