[Codeforces] [1084] ??

Posted lowbigpei

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[Codeforces] [1084] ??相关的知识,希望对你有一定的参考价值。

难度不高的一场Div2...(相比较于平时的Div2
因为E题官方给出的难度系数只有2100
一般D题都比这个要高了吧。。
链接

A. The Fair Nut and Elevator

暴力
读题意题
数据范围很小 直接暴力枚举一开始在哪里 直接按照题意模拟去最小值即可

#include<bits/stdc++.h>
#define fr(i,x,y) for(int i=x;i<=y;++i)
#define rf(i,x,y) for(int i=x;i>=y;--i)
#define LL long long
using namespace std;
const int N=110;
int a[N];

int main(){
    int n;scanf("%d",&n);
    fr(i,1,n) scanf("%d",&a[i]);
    int ans=1e8;
    fr(i,1,100){
        int pos=0;
        fr(j,1,n){
            pos+=(abs(j-i)+(j-1)+abs(i-1)+abs(i-1)+abs(j-1)+abs(i-j))*a[j];
        //  if(i==2) printf("%d %d
",j,pos);
        }       
        ans=min(ans,pos);
        //if(ans==pos) printf("%d %d
",i,ans);
    }
    printf("%d
",ans);
    return 0;
}

B.Kvass and the Fair Nut

贪心

题意: 你有(n)桶酒 第(i)桶酒有(v_i)升酒 每次你可以将任意一桶有酒的桶里倒1升到一个杯子里 要求杯子里的酒有(s)升 (一开始为空
问最后每桶酒中最少的最大是多少

题解: 酒的总量是一定的 所以先找出一开始每桶酒里的最小值 然后与(frac{s-sum}{3})比较即可

#include<bits/stdc++.h>
#define fr(i,x,y) for(int i=x;i<=y;++i)
#define rf(i,x,y) for(int i=x;i>=y;--i)
#define LL long long
using namespace std;
const int N=1e3+10;
LL a[N];

int main(){
    int n;LL m;scanf("%d%lld",&n,&m);
    LL sum=0,minn=1e18;
    fr(i,1,n) scanf("%lld",&a[i]),sum+=a[i],minn=min(minn,a[i]);
    if(sum<m) return printf("-1
"),0;
    printf("%lld
",min(minn,(sum-m)/n));
    return 0;
}

C.The Fair Nut and String

题意: 给你一个字符串(s) 让你找到满足一下条件的(p)数组数量
- 记(p)的长度为(k) 对于(1 leq i leq k) 都有(s_{p_i}='a')
- 对于(1 leq i leq k-1) 存在(p_i < j < p_{i+1}) 使得(s_j='b')

题解: 被b分开的a段 第(t)段设a的数量为(tmp_t) 则答案为$(tmp_1+1)(tmp_2+1) ... (tmp_tot+1) -1 $

#include<bits/stdc++.h>
#define fr(i,x,y) for(int i=x;i<=y;++i)
#define rf(i,x,y) for(int i=x;i>=y;--i)
#define LL long long
using namespace std;
const int N=1e5+10;
const int mod=1e9+7;
char lx[N];

void Mul(LL &x,LL y){
    x=x*y%mod;
}

void Add(LL &x,LL y){
    x=(x+y)%mod;
}

int main(){
    scanf("%s",lx+1);
    int len=strlen(lx+1);
    LL pos=1,tmp=0;
    fr(i,1,len){
        if(lx[i]=='a') tmp++;
        if(lx[i]=='b'){
            Mul(pos,tmp+1);
            tmp=0;
        }
    }
    Mul(pos,tmp+1);
    pos--;
    printf("%lld
",pos);
    return 0;
}

D.The Fair Nut and the Best Path

树型DP
题意: 在一棵树上求一条路径 使得点权+边权最大 从一点出发如果点权+边权<0了就不能走了

题解: 如果 从(u)(v)(v)(u) 是不一样的 那么肯定出现了点权+边权<0的情况了
很明显 如果点权+边权<0了我们也没有必要再往下走 为什么不看开一点从点权+边权<0的那个地方开始呢初始值是0肯定比负数要优啊
所以..直接按照像直径那样求就行了 小于0的不用加上去QwQ

#include<bits/stdc++.h>
#define fr(i,x,y) for(int i=x;i<=y;++i)
#define rf(i,x,y) for(int i=x;i>=y;--i)
#define LL long long
using namespace std;
const int N=3e5+10;
struct data{
    int nt,to;LL w;
}a[N<<1];
int head[N],cnt=0;
LL v[N],maxn=0;

void add(int x,int y,LL w){
    a[++cnt].to=y,a[cnt].w=w,a[cnt].nt=head[x],head[x]=cnt;
    a[++cnt].to=x,a[cnt].w=w,a[cnt].nt=head[y],head[y]=cnt;
}

LL dp(int u,int fa){
    LL tmp=0,kk=0;
    for(int i=head[u];i;i=a[i].nt){
        int to=a[i].to;
        if(to==fa) continue;
        LL res=dp(to,u);
        if(res-a[i].w<=0) continue;
        kk=max(kk,tmp+res-a[i].w+v[u]);
        tmp=max(tmp,res-a[i].w);
    }
    maxn=max(maxn,v[u]);
    maxn=max(maxn,kk);
    return tmp+v[u];
}

int main(){
    int n;scanf("%d",&n);
    fr(i,1,n) scanf("%lld",&v[i]);
    fr(i,2,n){
        int x,y;LL w;
        scanf("%d%d%lld",&x,&y,&w);
        add(x,y,w);
    }
    dp(1,0);
    printf("%lld
",maxn);
    return 0;
}

E.The Fair Nut and Strings

分类讨论 计数问题
我会告诉你我vp的时候题意都没读懂吗
题意:
给你两个数(n,k)还有两个长度为(n)的字符串(s)(t)
s的字典序小于等于t
([s,t])之间选出k个串 不同前缀的数目最大是多少
所有的串都只有a b两种字符构成
题解:
相当于你有很多种选择(k)个串的方法,每一种方法都对应了一个不同前缀的数量,求所有方法中最大的一个
如果先找好(k)个串 再去计算前缀 告辞!
我们可以考虑 算每一种长度的前缀在最终答案中被算到了几次

设前(i)位不同的前缀有(f_i)

考虑字典序问题,根据(s)(t)两个字符串的第(i+1)位的情况我们可以分类讨论四种情况

  • (s[i+1] = `a`, t[i+1] = `b`)
    (f_{i+1}=f_i*2) 显然前面(i)位之后接ab都是合法的

  • (s[i+1] = `a`, t[i+1] = `a`)
    (f_{i+1}=f_i*2 - 1) 除了前面(i)位字典序最大的串后面不能接b , 其他都可以随意的接上ab

  • (s[i+1] = ‘b’, t[i+1] = ‘b’)
    (f_{i+1}=f_i*2 - 1) 除了前面(i)位字典序最小的串后面不能接a,其他都可以随意的接上ab

  • (s[i+1] = ‘b’, t[i+1] = ‘a’)
    (f_{i+1}=f_i*2 - 2) 同理23333333333333333333333333333333333333333

#include<bits/stdc++.h>
#define fr(i,x,y) for(int i=x;i<=y;++i)
#define rf(i,x,y) for(int i=x;i>=y;--i)
#define LL long long
using namespace std;
const int N=5e5+10,mod=1e9+7;
char lx[N],ll[N];
LL maxn=1e18;

int main(){
    int n;LL k;scanf("%d%lld",&n,&k);
    scanf("%s%s",lx+1,ll+1);
    LL r=1,ans=0;int pd=0;
    fr(i,1,n){
        if(lx[i]<ll[i]) pd=1;
        if(pd){
            if(lx[i]==ll[i]) r=r*2-1;
            else if(lx[i]=='a'&&ll[i]=='b') r=r*2;
            else r=r*2-2;
        }
        ans+=min(r,k);
        r=min(r,maxn);
    }
    printf("%lld
",ans);
    return 0;
}

完结撒花花~

以上是关于[Codeforces] [1084] ??的主要内容,如果未能解决你的问题,请参考以下文章

CodeForces 1084A The Fair Nut and Elevator 题解

# codeforces 1084 考后总结

CodeForces 1084D The Fair Nut and the Best Path

CF 1084 D. The Fair Nut and the Best Path

Codeforces Round #437 (Div. 2, based on MemSQL Start[c]UP 3.0 - Round 2) E. Buy Low Sell High(代码片

闪存 CS6 错误:1084