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;
}