Atcoder Beginner Contest 418 A-D

AB

#include<bits/stdc++.h>
#define usetime() (double)clock () / CLOCKS_PER_SEC * 1000.0
using namespace std;
typedef long long LL;
void read(int& x){
	char c;
	bool f=0;
	while((c=getchar())<48) f|=(c==45);
	x=c-48;
	while((c=getchar())>47) x=x*10+c-48;
	x=(f ? -x : x);
	return;
}
int main(){
	int n;
	read(n);
	string s;
	cin>>s;
	if(s[s.size()-3]=='t'&&s[s.size()-2]=='e'&&s[s.size()-1]=='a'){
		printf("Yes");
	}
	else printf("No");
	return 0;
}
//^o^
#include<bits/stdc++.h>
#define usetime() (double)clock () / CLOCKS_PER_SEC * 1000.0
using namespace std;
typedef long long LL;
void read(int& x){
	char c;
	bool f=0;
	while((c=getchar())<48) f|=(c==45);
	x=c-48;
	while((c=getchar())>47) x=x*10+c-48;
	x=(f ? -x : x);
	return;
}
string s;
int main(){
	cin>>s;
	double ans=0;
	for(int i=0;i<s.size();i++){
		for(int j=i+2;j<s.size();j++){
			if(s[i]=='t'&&s[j]=='t'){
				int cnt=0;
				for(int k=i;k<=j;k++){
					if(s[k]=='t') ++cnt;
				}
				ans=max(ans,1.0*(cnt-2)/(j-i-1));
			}
		}
	}
	printf("%.9lf",ans);
	return 0;
}
//^o^

C

这应该叫抽屉原理

对于数量小于b的茶包种类,全拿。对于数量大于或等于b的茶包种类,拿b-1

分界点用二分去找

然后再拿上一包,就一定能满足了

#include<bits/stdc++.h>
#define usetime() (double)clock () / CLOCKS_PER_SEC * 1000.0
using namespace std;
typedef long long LL;
const int maxn=3e5+5;
void read(int& x){
	char c;
	bool f=0;
	while((c=getchar())<48) f|=(c==45);
	x=c-48;
	while((c=getchar())>47) x=x*10+c-48;
	x=(f ? -x : x);
	return;
}
int n,q;
int a[maxn];
LL sum[maxn];
int main(){
	read(n),read(q);
	for(int i=1;i<=n;i++){
		read(a[i]);
	}
	sort(a+1,a+n+1);
	for(int i=1;i<=n;i++){
		sum[i]=sum[i-1]+a[i];
	}
	int x;
	while(q--){
		read(x);
		int i=lower_bound(a+1,a+n+1,x)-a;
		if(i==n+1) printf("-1\n");
		else printf("%lld\n",sum[i-1]+1ll*(n-i+1)*(x-1)+1);
	}
	return 0;
}
//^o^

D

提供一种新思路,排列组合,这个思维难度可能会大一点

因为连续的1可以合并成1个1,这个1和旁边的0结合相当于没了,相当于1对完美序列无影响

然后看0,发现只要序列中有偶数0可以构成完美序列

转换问题,统计所有0的个数为偶数的子串个数

先算掉所有不含0的子序列,然后分两次第1,3,5,702,4,6,80

运用乘法分配律优化,累加这些0前的可能的起始位置数(也就是当前0到上一个0的位置的差)

每次乘上当前0后可能的结束位置数(到下一个0的位置的差)

#include<bits/stdc++.h>
#define usetime() (double)clock () / CLOCKS_PER_SEC * 1000.0
using namespace std;
typedef long long LL;
const int maxn=2e5+5;
void read(int& x){
	char c;
	bool f=0;
	while((c=getchar())<48) f|=(c==45);
	x=c-48;
	while((c=getchar())>47) x=x*10+c-48;
	x=(f ? -x : x);
	return;
}
int n;
string s;
int f[maxn],b[maxn];
vector<int> z;
int main(){
	read(n);
	cin>>s;
	int lst=-1;
	for(int i=0;i<s.size();i++){
		if(s[i]=='0'){
			z.push_back(i);
			f[i]=lst;
			if(lst!=-1) b[lst]=i;
			lst=i;
		}
	}
	if(lst!=-1) b[lst]=s.size();
	LL ans=0;
	z.push_back(s.size());
	f[z[z.size()-1]]=lst;
	for(int i=0;i<z.size();i++){
		int j=z[i]-f[z[i]]-1;
		ans+=1ll*j*(j+1)/2;
	}
	z.pop_back();
	LL p=0;
	for(int i=1;i<z.size();i+=2){
		p+=z[i-1]-f[z[i-1]];
		ans+=1ll*(b[z[i]]-z[i])*p;
	}
	p=0;
	for(int i=2;i<z.size();i+=2){
		p+=z[i-1]-f[z[i-1]];
		ans+=1ll*(b[z[i]]-z[i])*p;
	}
	printf("%lld",ans);
	return 0;
}
//^o^

E

分享一下我的思路,代码没有调出来

枚举两个点,计算斜率,再枚举其他点,看每个点的b值,两个点b值相同说明再同一直线上

所以建个桶,统计一下能平行的对数

应该没什么大毛病

posted @ 2025-08-09 22:17  huangems  阅读(30)  评论(0)    收藏  举报