AtCoder Beginner Contest 268

A

\(5\) 个数中有多少个不同的数。

法 1:用系统自带的 unique 函数。
法 2:用 set,因为 set 中元素互不相同,所以相同元素无法插入,输出 set 的大小即可。

B

给定两个字符串 \(S,T\),判断 \(S\) 是否为 \(T\) 的前缀。

枚举判断即可。

点击查看代码
#include <bits/stdc++.h>
using namespace std;
string s,t;
signed main()
{
	cin>>s>>t;
	if(s.size()>t.size()){cout<<"No";return 0;}
	int fl=1;
	for(int i=0;i<s.size();++i)
	{
		if(s[i]!=t[i])fl=0;
	}
	if(fl)cout<<"Yes";
	else cout<<"No";
	return 0;
}

C

记录一下转动多少次能使当前这个人满意,桶的值加一,枚举桶的下标,取最大值即可。

点击查看代码
#include <bits/stdc++.h>
using namespace std;
const int N=2e5+5;
int n,a[N],b[N];
signed main()
{
	cin>>n;
	for(int i=1;i<=n;++i)cin>>a[i];
    for(int i=1;i<=n;++i)b[(a[i]-i+n)%n]++;
    int ans=0;
    for(int i=0;i<n;++i)ans=max(ans,b[(i+n-1)%n]+b[i%n]+b[(i+1)%n]);
    cout<<ans;
	return 0;
}

D

搜索,需要注意一些细节,判重的时候使用 map 即可。

点击查看代码
#include <bits/stdc++.h>
using namespace std;
const int N=2e5+5;
int n,m,id[N],cnt=0;
string s[N],t[N],und[N];
unordered_map<string,int>mp;
void dfs(string x,int pos,int mr)
{
	if(mr>cnt)return;
	if(pos==n)
	{
		x+=s[id[n]];
		if(!mp[x]&&x.size()>2&&x.size()<17){cout<<x;exit(0);}
		return;
	}
	for(int i=0;i<=cnt-mr;++i)
	{
		dfs(x+s[id[pos]]+"_"+und[i],pos+1,mr+i);
	}
}
signed main()
{
	cin>>n>>m;
	for(int i=1;i<=n;++i){cin>>s[i];cnt+=s[i].size();}
	cnt+=n-1;if(cnt>16){cout<<-1;return 0;}cnt=16-cnt;
	for(int i=1;i<=16;++i)und[i]=und[i-1]+"_";
	for(int i=1;i<=m;++i){cin>>t[i];mp[t[i]]=1;}
	for(int i=1;i<=n;++i)id[i]=i;
	do
	{
		dfs("",1,0);
	}while(next_permutation(id+1,id+n+1));
	cout<<-1;
	return 0;
}

E

考虑每个人的不满意度与转数的关系,发现构成一个分三段的函数,每一段都是一个一次函数。
可以分类讨论求出每一段的斜率和截距。
而总不满意度即为每个人的函数的叠加,可以通过差分求的。
这样就求出了总函数的表达式,枚举求出最小值即可。

点击查看代码
#include <bits/stdc++.h>
#define int long long
using namespace std;
const int N=2e5+5;
int n,p[N],sumk[N],sumb[N];
void upd(int l,int r,int k,int b)
{
	if(l>r)return;
	sumk[l]+=k;sumk[r+1]-=k;
	sumb[l]+=b;sumb[r+1]-=b;
}
void add(int x)
{
	if(x<n/2){upd(0,x-1,-1,x);upd(x,x+n/2,1,-x);upd(x+n/2+1,n-1,-1,n+x);}
	else{upd(x-n/2,x,-1,x);upd(x+1,n-1,1,-x);upd(0,x-n/2-1,1,n-x);}
}
signed main()
{
	cin>>n;
	for(int i=0;i<n;++i){cin>>p[i];add((p[i]-i+n)%n);}
	for(int i=1;i<n;++i){sumk[i]+=sumk[i-1];sumb[i]+=sumb[i-1];}
	int ans=1e15;
	for(int i=0;i<n;++i)ans=min(ans,sumk[i]*i+sumb[i]);
	cout<<ans;
	return 0;
}

F

比较有趣的贪心。

\(X\)\(S\)X的个数,\(Y\)\(S\) 中所有数字的总和。
考虑一个排列 \(P_1,P_2,\cdots,P_i,P_{i+1},\cdots,P_n\),如果交换 \(i\)\(i+1\),原排列变为 \(P_1,P_2,\cdots,P_{i+1},P_i,\cdots,P_n\),其他位置对答案的贡献没有改变,其实只是改变了 \(P_i\)\(P_{i+1}\) 的位置,考虑答案有什么改变。

\(P_i,P_{i+1}\) 内部的贡献没有改变,其实改变的只是 \(P_{i+1}\)\(P_i\) 的贡献变为了 \(P_i\)\(P_{i+1}\) 的贡献,就是 \(X_i\times Y_{i+1}\) 变成了 \(X_{i+1}\times Y_i\)
若交换更优,则需保证

\[X_{i+1}\times Y_i>X_i\times Y_{i+1} \]

\[\dfrac{X_i}{Y_i}<\dfrac{X_{i+1}}{Y_{i+1}} \]

因此,按 \(\dfrac{X}{Y}\) 降序排列即可。

点击查看代码
#include <bits/stdc++.h>
#define int long long
using namespace std;
const int N=2e5+5;
int n;
struct node{int x,y;string s;}a[N];
bool cmp(node q,node w)
{
	return q.x*w.y>q.y*w.x;
}
signed main()
{
	cin>>n;
	for(int i=1;i<=n;++i)
	{
		cin>>a[i].s;
		for(int j=0;j<a[i].s.size();++j)
			if(a[i].s[j]=='X')a[i].x++;
			else a[i].y+=a[i].s[j]-'0';
	}
	sort(a+1,a+n+1,cmp);
	string ans;
	for(int i=1;i<=n;++i)
		ans+=a[i].s;
	int len=ans.size(),sum=0,cnt=0;
	for(int i=len-1;i>=0;--i)
	{
		if(ans[i]=='X')cnt+=sum;
		else sum+=ans[i]-'0';
	}
	cout<<cnt;
	return 0;
}
posted @ 2022-09-11 15:38  lnwhl  阅读(129)  评论(1编辑  收藏  举报