首页 > 其他分享 >[题解]AtCoder Beginner Contest 383(ABC383) A~F

[题解]AtCoder Beginner Contest 383(ABC383) A~F

时间:2024-12-15 22:58:08浏览次数:4  
标签:AtCoder Beginner int 题解 long yy using include define

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

标签:AtCoder,Beginner,int,题解,long,yy,using,include,define
From: https://www.cnblogs.com/Sinktank/p/18608615

相关文章

  • 题解:(A)[EPXLQ2024 fall round] 风吹起了从前
    (A)[EPXLQ2024fallround]风吹起了从前题意给定\(n\)个字符串\(a_1\)到\(a_n\)。第\(i\)个字符串拥有一个深度值\(r_i\),有一个价值\(v_i\)。再给你\(m\)次询问,每次给出一个字符串\(t\)和深度\(d\),求以\(t\)为前缀且深度值小于\(d\)的字符串价值之和。Soluio......
  • 题解:P11372 「CZOI-R2」加训
    暴力三重循环,枚举学生,障碍和老师,再判断是否合法。时间复杂度:\(\Theta(mxy)\)。但是会TLE。暴力优化用数组\(oier\)来存储二元组\((x,y)\)对应的坐标\(z\)。这样就省去的开三维数组的成本。然后只用枚举学生和老师,再判断维度坐标不同数是否为\(k-1\)个,以及中间有没......
  • 题解:P11319 [NOISG2020 Qualification] Cryptography
    康托展开模版给大家一个式子,这个式子就是康托展开的模版。\(rank=1+\sum_{i=1}^{n}a_n\times(n-i)!\)然后我们对这个排列\(P\)进行离散化,最后直接来个康托展开的模版就行了。代码#include<iostream>#include<cstdio>#include<cstring>#include<algorithm>usi......
  • 题解:P11389 [COCI 2024/2025 #1] 等级 / Hijerarhija
    思路因为一棵树的本质是一个图,所以我们可以认为入度为\(0\)的节点就是这个树的根。所以我们统计有几个根,以及是已经作为根的。最后去统计有多少个根就行了。存储父子关系可以用unordered_map。代码#include<iostream>#include<cstdio>#include<cstring>#include<algori......
  • 题解:AT_abc032_d [ABC032D] ナップサック問題
    思路subtask1直接暴力搜索即可。subtask2普通的01背包,直接\(dp\)即可。subtask3改变\(dp\)的状态,设\(dp_i\)表示价值为\(i\)时用的最小体积,那么就直接在里面找最小值就行。代码#include<iostream>#include<cstdio>#include<algorithm>#include<cstring>usi......
  • 题解:B4070 [GESP202412 五级] 奇妙数字
    思路可以考虑质因数分解,使得最后每一个奇妙数字以及它们的乘积是\(n\)的因数。奇妙数字的定义:\(x=p^a\)。所以在质因数分解的过程中,我们统计每个质因数有多少,然后统计可以分解成多少个奇妙数字。代码#include<iostream>#include<cstdio>#include<cstring>#include<algor......
  • 网站使用CDN出现ttf woff等字体跨域问题解决方案
    如果cdn域名+资源路径是可以通过浏览器url地址栏打开的那么一般是因为nginx配置的原因,找到nginx的配置文件添加以下代码: #允许指定域名访问;location~.*.(eot|ttf|ttc|otf|eot|woff|woff2|svg)(.*){ add_headerAccess-Control-Allow-Originhttp(s)://这里填写你的域名;......
  • AtCoder Beginner Contest 384 Solution
    A-aaaadaa(abc384A)题目大意给个长度为n的字符串,以及两个字母a和b,要求把字符串中不是a的字符全部都变成b。解题思路一个循环判断一下就行了。代码#include<bits/stdc++.h>usingnamespacestd;intmain(){intn;chara,b;cin>>n>>a>>b;st......
  • [BZOJ3569] DZY Loves Chinese II 题解
    考虑不联通的情况。图不好做,就造一棵生成树出来,由于是无向图,所以只有树边和返祖边。发现在一条树边断开后,生成树会分成两个连通块,由覆盖这条树边的返祖边链接,只有这些返祖边也全部断开,原图才会不联通。想到异或的优良性质。我们给所有返祖边在\([0,2^{63})\)中随机一个值作为......
  • 问题解决:windows主机开机不插屏幕不能自动进入桌面
    操作系统一般都有这种设定,不论是windows还是Linux系统,那就是主机开机不插屏幕不能自动进入桌面操作系统一般都有这种设定,不论是windows还是Linux系统,那就是主机开机不插屏幕不能自动进入桌面。如何解决:给主机插上“屏幕欺骗器”操作系统在启动的过程中,在进入系统之前会读取......