目录
难度不高的一场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\n",j,pos);
}
ans=min(ans,pos);
//if(ans==pos) printf("%d %d\n",i,ans);
}
printf("%d\n",ans);
return 0;
}
B.Kvass and the Fair Nut
贪心
题意: 你有\(n\)桶酒 第\(i\)桶酒有\(v_i\)升酒 每次你可以将任意一桶有酒的桶里倒1升到一个杯子里 要求杯子里的酒有\(s\)升 (一开始为空
问最后每桶酒中最少的最大是多少
题解: 酒的总量是一定的 所以先找出一开始每桶酒里的最小值 然后与\(\frac{s-sum}{n}\)比较即可
#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\n"),0;
printf("%lld\n",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\n",pos);
return 0;
}
D.The Fair Nut and the Best Path
树型DP
题意: 在一棵树上求一条路径 使得点权+边权最大 从一点出发如果点权+边权<0了就不能走了
题解: 如果 从\(u\)到\(v\) 和 \(v\) 到 \(u\) 是不一样的 那么肯定出现了点权+边权<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\n",maxn);
return 0;
}
E.The Fair Nut and Strings
分类讨论
计数问题
题意:
给你两个数\(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\)位之后接a
或b
都是合法的\(s[i+1] = `a`, t[i+1] = `a`\)
\(f_{i+1}=f_i*2 - 1\) 除了前面\(i\)位字典序最大的串后面不能接b
, 其他都可以随意的接上a
或b
\(s[i+1] = ‘b’, t[i+1] = ‘b’\)
\(f_{i+1}=f_i*2 - 1\) 除了前面\(i\)位字典序最小的串后面不能接a
,其他都可以随意的接上a
或b
\(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\n",ans);
return 0;
}
完结撒花花~