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