ABC328
A
略
B
用set模拟即可
int cal(int x,int y){
set<int>st;
set<int>st2;
while(x){
st.insert(x%10);x/=10;
}
while(y){
st2.insert(y%10);y/=10;
}
if(st==st2&&st.size()==1)return 1;
return 0;
}
void solve(){
int n;cin>>n;
int cnt=0;
rep(i,1,n){
int x;cin>>x;
rep(j,1,x){
if(cal(i,j))cnt++;
}
}
cout<<cnt<<endl;
}
C
题意:给定一个字符串,当s[i]=s[i-1]说这个字符是满足条件的,给定q次询问和[l,r],问区间内有多少个满足条件的字符
思路:
把满足条件的字符进行前缀和处理即可,注意答案变为了pre[r]-pre[l]
D
题意:
给定一个由A,B,C组成的字符串,遇到ABC子串就删除,同时把子串两边的子串连接起来,直到字符串中没有ABC为止
思路:
直接暴力可能会超时
不妨把字符串看成一个字符栈,每当该字符串的后缀3个字符为ABC时就删除
void solve(){
string s;cin>>s;
int n=s.size();s=" "+s;
int ok=1;
stack<char>stk;
string t;t=" "+t;
rep(i,1,n){
t+=s[i];
if(t.size()>=4){
if(t.substr(t.size()-3,3)=="ABC"){
t.erase(t.size()-3,3);
// t.pop_back();
// t.pop_back();
// t.pop_back();
}
}
}
rep(i,1,t.size()-1){
cout<<t[i];
}
}
E
题意:给定一个图,求模K意义下的最小生成树边权之和
思路:
显然不能直接用kruskal之类的算法求解
N<=8,M<=28,所以考虑暴力枚举边的子集(2e8)
取出其中的n-1个,再利用并查集判断连通性,答案取min即可
int n,m,k;
int f[15];
int find(int x){
if(f[x]!=x){
f[x]=find(f[x]);
}return f[x];
}
void merge(int x,int y){
if(find(x)!=find(y)){
f[find(x)]=find(y);
}
}
void build(){
rep(i,1,n)f[i]=i;
}
int ans=llmax;
void solve(){
cin>>n>>m>>k;
vector<pair<pii,int>>e;
rep(i,1,m){
int u,v,w;cin>>u>>v>>w;
e.pb({{u,v},w});
}
for(int i=0;i<(1ll<<m);i++){
if(__builtin_popcount(i)!=(n-1))continue;
int sum=0;
build();
for(int j=0;j<m;j++){
if(i&(1ll<<j)){
int u=e[j].fi.fi,v=e[j].fi.se,w=e[j].se;
merge(u,v);
sum+=w;
}
}
int fa=find(1);
int ok=1;
rep(i,1,n){
if(find(i)!=fa)ok=0;
}
if(ok)ans=min(ans,sum%k);
}
cout<<ans<<endl;
}
F
题意:给定一系列三元组(a,b,c),从左往右遍历能构造出X满足X[a[i]]-X[b[i]]=c
思路:
带权并查集
让边权表示相对大小关系,即如果dis[x]=dis[y]+c,(dis数组为节点到该连通块根节点的距离),表示x比y大c
不在同一个连通块的节点没有相互大小关系
所以merge的时候判断,如果两个节点在同一个连通块,判断dis[x]是否等于dis[y]+c即可
如果两个节点不在同一个连通块,则需要连接两个节点的根节点(将其中一个根节点与另一个根节点进行连接,并将大小关系设置好)
int f[maxn];
int val[maxn];
int find(int x){
if(f[x]!=x){
int p=f[x];
f[x]=find(f[x]);
val[x]+=val[p];
}
return f[x];
}
int merge(int x,int y,int c){
if(find(x)!=find(y)){
int fx=find(x);
int fy=find(y);
f[fx]=fy;
val[fx]+=c+val[y]-val[x];
return 1;
}else{
if(val[x]-val[y]!=c)return 0;
return 1;
}
}
void solve(){
int n,q;cin>>n>>q;
rep(i,1,n)f[i]=i;
rep(i,1,q){
int u,v,w;cin>>u>>v>>w;
if(merge(u,v,w))cout<<i<<' ';
}
cout<<endl;
}

浙公网安备 33010602011771号