[题解]AtCoder Beginner Contest 384(ABC384) A~F
A - aaaadaa
按题意模拟即可。
点击查看代码
#include<bits/stdc++.h>
using namespace std;
int n;
char c1,c2;
string s;
signed main(){
cin>>n>>c1>>c2>>s;
for(int i:s){
if(i==c1) cout<<c1;
else cout<<c2;
}
return 0;
}
B - ARC Division
按题意模拟即可。
点击查看代码
#include<bits/stdc++.h>
using namespace std;
int n,r,d,a;
signed main(){
cin>>n>>r;
while(n--){
cin>>d>>a;
if(d==1){
if(r>=1600&&r<=2799) r+=a;
}else{
if(r>=1200&&r<=2399) r+=a;
}
}
cout<<r;
return 0;
}
C - Perfect Standings
枚举得分情况,按分数从大到小为第一关键字,字典序从小到大为第二关键字进行排序,输出即可。
点击查看代码
#include<bits/stdc++.h>
using namespace std;
int a[5],idx;
struct ttt{int num;string s;}ans[514];
signed main(){
for(int i=0;i<5;i++) cin>>a[i];
for(int i=1;i<32;i++){
string s="";
int sum=0;
for(int j=0;j<5;j++){
if((i>>j)&1) s+=('A'+j),sum+=a[j];
}
ans[++idx]={sum,s};
}
sort(ans+1,ans+1+idx,[](ttt a,ttt b){
return a.num==b.num?a.s<b.s:a.num>b.num;
});
for(int i=1;i<=idx;i++) cout<<ans[i].s<<"\n";
return 0;
}
D - Repeated Sequence
令\(t=\sum_{i=1}^n a[i]\),则满足条件的区间,去除中间完整的周期,剩下的部分就是\(a\)的一个前缀和一个后缀,它们的和最大是\(2\times (s\bmod t)\),所以我们只需要判断是否存在一个前缀和一个后缀的和是\((s\bmod t)\)或\((s\bmod t)+t\)即可,可以用map
将所有前缀和(包括\(0\))扔进去。
注意特判\(s<t\)时必须仅计算\((s\bmod t)\)的答案。
点击查看代码
#include<bits/stdc++.h>
#define int long long
#define N 200010
using namespace std;
int n,s,a[N],pa[N];
unordered_set<int> se;
signed main(){
cin>>n>>s;
for(int i=1;i<=n;i++) cin>>a[i];
for(int i=1;i<=n;i++) pa[i]=pa[i-1]+a[i],se.insert(pa[i]);
se.insert(0);
int sum=s%pa[n];
bool f=0;
for(int i=1;i<=n;i++){
int sa=pa[n]-pa[i-1];
if(se.count(sum-sa)){
f=1;
break;
}
}
if(f){
cout<<"Yes\n";
return 0;
}
if(s>=pa[n]){
sum+=pa[n];
for(int i=1;i<=n;i++){
int sa=pa[n]-pa[i-1];
if(se.count(sum-sa)){
f=1;
break;
}
}
if(f){
cout<<"Yes\n";
return 0;
}
}
cout<<"No\n";
return 0;
}
赛后看了其他题解,其实没必要那么麻烦,将每个后缀丢进set
后,依次遍历每个前缀\(a[1\sim i]\),如果\(s\ge a[i]\)且存在一个后缀的值为\((s-a[i])\bmod t\),就是合法的。
点击查看代码
#include<bits/stdc++.h>
#define int long long
#define N 200010
using namespace std;
int n,s,a[N];
unordered_set<int> se;
bool solve(){
for(int i=0;i<n;i++) se.insert(a[n]-a[i]);
for(int i=0;i<n;i++){
if(s<a[i]) return 0;
if(se.count((s-a[i])%a[n])) return 1;
}
return 0;
}
signed main(){
cin>>n>>s;
for(int i=1;i<=n;i++) cin>>a[i],a[i]+=a[i-1];
cout<<(solve()?"Yes\n":"No\n");
return 0;
}
E - Takahashi is Slime 2
优先队列维护可扩展到的格子的力量值,每次取最小判断能否扩展,如果能扩展就累加答案并更新可扩展到的格子,否则直接输出答案。
时间复杂度\(O(nm\log nm)\)。
点击查看代码
#include<bits/stdc++.h>
#define N 510
#define M 510
#define int long long
using namespace std;
int n,m,lim,sx,sy,a[N][M],dx[4]{-1,0,1,0},dy[4]{0,1,0,-1};
bitset<M> vis[N];
struct Status{int v,x,y;};
struct cmp{bool operator()(Status a,Status b){return a.v>b.v;}};
priority_queue<Status,vector<Status>,cmp> q;
signed main(){
cin>>n>>m>>lim>>sx>>sy;
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
cin>>a[i][j];
}
}
vis[sx][sy]=1;
for(int i=0;i<4;i++){
int xx=sx+dx[i],yy=sy+dy[i];
if(xx<1||yy<1||xx>n||yy>m) continue;
q.push({a[xx][yy],xx,yy});
vis[xx][yy]=1;
}
int V=a[sx][sy];
while(!q.empty()){
auto t=q.top();
q.pop();
int v=t.v,x=t.x,y=t.y;
if(v>=(V+lim-1)/lim) break;
V+=v;
for(int i=0;i<4;i++){
int xx=x+dx[i],yy=y+dy[i];
if(xx<1||yy<1||xx>n||yy>m||vis[xx][yy]) continue;
q.push({a[xx][yy],xx,yy});
vis[xx][yy]=1;
}
}
cout<<V;
return 0;
}
F - Double Sum 2
不难发现,\(f(x)\)表示将\(x\)二进制表示下的后导零去除的结果。
因此,考虑枚举两个数和二进制表示中 末尾\(0\)的数量。
两个数的和的末尾有至少\(k\)个\(0\),当且仅当他们的后\(k\)位相加为\(2^k\)。可以开一个桶来统计\(a[i]\)的后\(k\)位的值,对于每个\(k\),可以\(O(n)\)统计出\(f[k]\),即“两个数的和的末尾有至少\(k\)个\(0\)”的所有\(a[i]+a[j]\)之和。
对\(f\)求差分数组,即可得到\(g[k]\),即“两个数的和的末尾有恰好\(k\)个\(0\)”的所有\(a[i]+a[j]\)之和。答案即为\(\sum\limits_{i=0} g[i]\div 2^i\)。
时间复杂度\(O(n\log V)\)。
点击查看代码
#include<bits/stdc++.h>
#define N 200010
#define int long long
using namespace std;
int inv(int x,int s){return s&(s+1-(x&s));}
int n,a[N],sum[1<<26],cnt[1<<26],f[26],ans;
signed main(){
cin>>n;
for(int i=1;i<=n;i++) cin>>a[i];
for(int k=25;~k;k--){
int s=(1<<k)-1;
for(int i=1;i<=n;i++){
sum[a[i]&s]+=a[i],cnt[a[i]&s]++;
f[k]+=sum[inv(a[i],s)]+cnt[inv(a[i],s)]*a[i];
}
for(int i=1;i<=n;i++) sum[a[i]&s]=cnt[a[i]&s]=0;
ans+=(f[k]-f[k+1])>>k;
}
cout<<ans<<"\n";
return 0;
}