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,7个0和2,4,6,8个0
运用乘法分配律优化,累加这些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值相同说明再同一直线上
所以建个桶,统计一下能平行的对数
应该没什么大毛病

浙公网安备 33010602011771号