首页 > 其他分享 >ABC 328 题解

ABC 328 题解

时间:2023-11-12 11:22:18浏览次数:39  
标签:10 ABC return int 题解 cin vec 328 find

A

直接模拟即可。

cin>>n>>m;
for(int i=1;i<=n;++i){
	int x; cin>>x;
	if(x<=m)sum+=x;
}
cout<<sum;

B

直接模拟即可。

int n,ans;
bool chk(int x,int y){
	int dig=x%10; x/=10;
	while(x){
		if(x%10!=dig)return 0;
		x/=10;
	}
	while(y){
		if(y%10!=dig)return 0;
		y/=10;
	} return 1;
}
void Solve(){
	cin>>n;
	for(int i=1;i<=n;++i){
		int x; cin>>x;
		for(int j=1;j<=x;++j){
			if(chk(i,j))++ans;
		}
	}
	cout<<ans;
}

C

由于没有修改操作,预处理每个会出现重复两次的位置,并且将他们加入数组(或者 \(\texttt{vector}\))中,二分查找即可。

int n,m;
string s;
vector<int>vec;
void Solve(){
	cin>>n>>m;
	cin>>s;
	for(int i=0;i<n-1;++i){
		if(s[i]==s[i+1])vec.push_back(i+1);
	}vec.push_back(1145141919);
	while(m--){
		int l,r; cin>>l>>r;
		int p1=lower_bound(vec.begin(),vec.end(),l)-vec.begin();
		int p2=lower_bound(vec.begin(),vec.end(),r)-vec.begin()-1;
		cout<<p2-p1+1<<'\n';
	}
}

D

注意到删除操作会使得字符串拼接起来,因此考虑使用栈来模拟这个删除过程。

只要栈顶的三个元素是 \(\texttt{C,B,A}\) 就说明字符串中出现了 \(\texttt{ABC}\),栈顶弹出三个元素即可。

int n,m;
string s;
vector<char>vec;
void Solve(){
	cin>>s; int x=0;
	for(char ch:s){
		vec.push_back(ch); ++x;
		if(x>=3){ //栈顶要有三个元素才能判断
			if(vec[x-3]=='A' && vec[x-2]=='B' && vec[x-1]=='C'){
				vec.pop_back(); vec.pop_back(); vec.pop_back(); x-=3;
			}
		}
	}
	for(char ch:vec)cout<<ch;
}

E

发现一个很鬼畜的数据范围:\(1 \leq n \leq 8\)。

因此考虑直接顺序搜索每一条可行的边,只要边满足生成树的条件就尝试加入这条边,当选择的边数量是 \(n-1\) 时就更新最终答案,注意取模以及开 \(\texttt{long long}\)。

#define N 15
#define int long long
int n,m,k,sum,ans=1e18,u[N],v[N],w[N],f[N],p=1;
int find(int x){
	return x==f[x]?x:f[x]=find(f[x]);
}
vector<int>e[N];
vector<int>vec;
bool chk(int x){ //因为 n<=8 所以每次判断时候直接重新开并查集然后查询即可
	for(int i=1;i<=n;++i)f[i]=i;
	for(int i:vec){
		int fx=find(u[i]),fy=find(v[i]);
		f[fx]=fy;
	} return find(u[x])!=find(v[x]);
}
void dfs(){
	if(vec.size()==n-1){ //vector 存选中的边,数量是 n-1 就更新答案
		ans=min(ans,sum%k);
		return;
	} int t=p; for(int i=p;i<=m;++i){ //顺序搜索
		if(chk(i)){ //这条边是否可行
			vec.push_back(i);
			sum+=w[i]; p=i;
			dfs();
			vec.pop_back(); p=t;
			sum-=w[i];
		}
	}
}
void Solve(){
	cin>>n>>m>>k;
	for(int i=1;i<=m;++i)cin>>u[i]>>v[i]>>w[i];
	dfs(); cout<<ans;
}

F

先读懂题意。发现题目是想要尝试加入编号为 \(i\) 的约束条件 \(X_{a_i}-X_{b_i}=d_i\),因此直接使用带权并查集维护这一过程即可。在有基础的情况下 F 甚至比 E 简单。如果没有写过带权并查集可以写一下洛谷的银河英雄传说一题。

int n,m,q,f[N],g[N];
int find(int x){
	if(f[x]==x)return x;
	int t=f[x]; f[x]=find(f[x]);
	g[x]=g[x]+g[t]; return f[x]; //路径压缩下更新权值
}
void Solve(){
	cin>>n>>q;
	for(int i=1;i<=n;++i)f[i]=i;
	for(int i=1;i<=q;++i){
		int u,v,w; cin>>u>>v>>w;
		int fx=find(u),fy=find(v);
		if(fx==fy && g[u]!=g[v]+w)continue; //当前情况不能满足约束条件
		cout<<i<<" "; if(fx!=fy){
			f[fx]=fy; g[fx]=-g[u]+g[v]+w; //更新权值
		}
	}
}

说句题外话,CF1850H 是类似题,评分 \(1700\)。

G

咕咕咕。自己正在补。

标签:10,ABC,return,int,题解,cin,vec,328,find
From: https://www.cnblogs.com/McIron233/p/abc328.html

相关文章

  • ABC328F 题解
    blog。提供一个普通并查集+启发式合并做法。考虑直接维护\(X_i\)。对于\(X_u-X_v=w\),分四种情况。\(X_u,X_v\)都没被维护过。直接钦定\(X_u\getsw,X_v\gets0\),以后再改。\(X_u\)没被维护过,\(X_v\)被维护过。显然\(X_u\getsX_v+w\)。\(X_v\)没被维护过,\(X_u\)被......
  • ABC328G 题解
    blog。剩下几分钟的时候胡出来了,但是时间不够,痛失AK/dk。\(N\le22\),显然状压DP。\(dp_s\)表示确定\(s\)集合的元素所需的代价(这些元素都放在最前面)。确定了\(s\)后,发现会有\(\operatorname{popcount}(s)\)个元素堆在前面,那么枚举\([L,R]\)接在后面,也就是\([\opera......
  • [题解] CF407E k-d-sequence
    k-d-sequence给你一个长为\(n\)的序列,求最长的子区间使得它加入至多\(k\)个数后,重排后是公差为\(d\)的等差数列。\(n,k\le2\times10^5\),\(0\led\le10^9\)。公差是\(d\)的等差数列模\(p\)的值应该相等,所以把序列按极长模\(p\)同余的连续段分组。对于同......
  • [题解] CF505E Mr. Kitayuta vs. Bamboos
    Mr.Kitayutavs.Bamboos给定\(n\)个数\(h_{1\dotsn}\)。你需要进行\(m\)轮操作,每轮操作为\(k\)次修改,每次修改可以选择一个数\(h_i\)修改为\(\max(h_i-p,0)\)。每轮操作后每个\(h_i\)将会被修改为\(h_i+a_i\)。你需要最小化最终\(h_{1\cdotsn}\)中......
  • AtCoder Beginner Contest 328
    A-NotTooHard(abc328A)题目大意给定\(n\)个数字和一个数\(x\)。问不大于\(x\)的数的和。解题思路按找要求累计符合条件的数的和即可。神奇的代码#include<bits/stdc++.h>usingnamespacestd;usingLL=longlong;intmain(void){ios::sync_with_stdi......
  • AtCoder Beginner Contest 328
    A傻逼题。B傻逼题C傻逼题D不难发现,每次添加一个字符,如果可以当前的答案组成ABC就删。然后模拟即可。E两种方法。二进制枚举使用了哪些边。可以发现有用的状态只有\(\binom{m}{n-1}\),上限大概\(10^5\),剩余无用状态过了就行。复杂度\(O(m2^m)\),但是跑的特别不满。......
  • 【题解 P8763】[蓝桥杯 2021 国 ABC] 异或变换
    同楼上dalao做法:#include<iostream>#include<algorithm>#include<cstdio>#include<cmath>#include<cstring>#include<string>#include<cstdlib>#include<bitset>usingnamespacestd;constintN=1e4+10......
  • ABC328题解(C-G)
    A/B较为简单,略去。C预处理一下,然后前缀和就好了。时间复杂度\(O(n)\)。D用链表来记录字符串。注意到每次能够消去意味着链表上连续三个节点拼起来是ABC,然后从左到右一个个算就行了。匹配到的话把三个节点一起删掉。时间复杂度\(O(n)\)。E注意到\(N\le8,M\le28\)......
  • 2022新生赛 玩石头 题解
    这题乍一看是个背包,但是它对背包物品的重量进行了限制,而且我们没有手段得知当前物品是否大于前面所有物品。研究发现,纪念品最大价值不会超过4000.因此我们可以用类似于01背包的做法,以纪念品价值作为重量,纪念品重量作为价值来dp.打表可以发现,在给定数据的范围下,石头塔最多为三十层,......
  • P9836 种树 题解
    蒟蒻在考场上花了2h45minAC本题通过高度求宽度定义一棵树的宽度为它高度的正因数个数我们可以预处理\(10^4\)之内素数。 for(lli=2;i<=10000;i++){ if(ok[i]==0){ ok[i]=i; pr[++nP]=i; } for(llj=1;i*pr[j]<=10000&&j<=nP;j++){ ok[i*pr[j]]=......