昨天打的,补了一天半才补完。。。
A:水题
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include<bits/stdc++.h> #define fi first #define se second #define mp make_pair #define pb push_back #define pi acos(-1.0) #define ll long long #define mod 1000000007 #define C 0.5772156649 #define ls l,m,rt<<1 #define rs m+1,r,rt<<1|1 #define pil pair<int,ll> #define pii pair<int,int> #define ull unsigned long long #define base 1000000000000000000 #define fio ios::sync_with_stdio(false);cin.tie(0) using namespace std; const double g=10.0,eps=1e-12; const int N=50000+10,maxn=2000+10,inf=0x3f3f3f3f; int main() { int a,b,c; scanf("%d%d%d",&a,&b,&c); int ans=10000; for(int i=1;i<=100;i++) { ans=min(ans,abs(i-a)+abs(i-b)+abs(i-c)); } printf("%d ",ans); return 0; } /******************** ********************/
B:也很水,模拟即可
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include<bits/stdc++.h> #define fi first #define se second #define mp make_pair #define pb push_back #define pi acos(-1.0) #define ll long long #define mod 1000000007 #define C 0.5772156649 #define ls l,m,rt<<1 #define rs m+1,r,rt<<1|1 #define pil pair<int,ll> #define pii pair<int,int> #define ull unsigned long long #define base 1000000000000000000 #define fio ios::sync_with_stdio(false);cin.tie(0) using namespace std; const double g=10.0,eps=1e-12; const int N=50000+10,maxn=2000+10,inf=0x3f3f3f3f; vector<string>in,out; int main() { fio; int n; string s; cin>>n>>s; bool inside=0; string te=""; for(int i=0;i<n;i++) { if(s[i]=='(') { if(te!="")out.pb(te); te=""; inside=1; } else if(s[i]==')') { if(te!="")in.pb(te); te=""; inside=0; } else if(s[i]!='_')te+=s[i]; else { if(inside)in.pb(te); else out.pb(te); te=""; } } if(te!="") { if(inside)in.pb(te); else out.pb(te); } int maxx=0; for(int i=0;i<out.size();i++) maxx=max(maxx,(int)out[i].size()); int num=0; for(int i=0;i<in.size();i++) if(in[i]!="") num++; cout<<maxx<<" "<<num<<" "; return 0; } /******************** ********************/
C:题意:给一些n个数,要改变最小的次数来使得1到m出现最少的次数最大
题解:肯定n/m就是次数,然后依次找需要改变的地方填充即可
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include<bits/stdc++.h> #define fi first #define se second #define mp make_pair #define pb push_back #define pi acos(-1.0) #define ll long long #define mod 1000000007 #define C 0.5772156649 #define ls l,m,rt<<1 #define rs m+1,r,rt<<1|1 #define pil pair<int,ll> #define pii pair<int,int> #define ull unsigned long long #define base 1000000000000000000 #define fio ios::sync_with_stdio(false);cin.tie(0) using namespace std; const double g=10.0,eps=1e-12; const int N=4000+10,maxn=2000+10,inf=0x3f3f3f3f; int a[N]; int num[N]; bool ok[N]; int main() { int n,m; scanf("%d%d",&n,&m); for(int i=0;i<n;i++) { scanf("%d",&a[i]); if(a[i]<=m)num[a[i]]++; } int ans1=n/m,ans2=0; for(int i=1;i<=m;i++) { int te=min(ans1,num[i]); for(int j=0;j<n;j++) { if(!ok[j]&&a[j]==i&&te) { ok[j]=1; te--; } } } // for(int i=0;i<n;i++)printf("%d ",ok[i]); stack<pii>s; for(int i=1;i<=m;i++) { if(num[i]<ans1) { ans2+=ans1-num[i]; s.push(mp(i,ans1-num[i])); } } printf("%d %d ",ans1,ans2); for(int i=0;i<n;i++) { if(!ok[i]) { if(!s.empty()) { a[i]=s.top().fi; s.top().se--; if(s.top().se==0)s.pop(); } } printf("%d ",a[i]); } puts(""); return 0; } /******************** ********************/
D:傻逼题,爆搜即可(当时爆搜写爆了,然后mle。。。。原来递归太深也是会mle的)
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include<bits/stdc++.h> #define fi first #define se second #define mp make_pair #define pb push_back #define pi acos(-1.0) #define ll long long #define mod 1000000007 #define C 0.5772156649 #define ls l,m,rt<<1 #define rs m+1,r,rt<<1|1 #define pil pair<int,ll> #define pii pair<int,int> #define ull unsigned long long #define base 1000000000000000000 #define fio ios::sync_with_stdio(false);cin.tie(0) using namespace std; const double g=10.0,eps=1e-12; const int N=100+10,maxn=2500+10,inf=0x3f3f3f3f; int n,m,k; char ma[N][N]; bool vis[N][N]; struct lake{ int x,y,water; bool operator <(const lake& rhm)const{ return water<rhm.water; } }a[maxn]; int num; void dfs(int x,int y) { if(x<0||x>=n||y<0||y>=m||vis[x][y]||ma[x][y]=='*')return ; if(x==0||x==n-1||y==0||y==m-1)num=-1; if(num!=-1)num++; vis[x][y]=1; dfs(x+1,y); dfs(x-1,y); dfs(x,y-1); dfs(x,y+1); } void land(int x,int y) { if(x<0||x>=n||y<0||y>=m||ma[x][y]=='*')return ; ma[x][y]='*'; land(x+1,y); land(x-1,y); land(x,y+1); land(x,y-1); } int main() { scanf("%d%d%d",&n,&m,&k); for(int i=0;i<n;i++) scanf("%s",ma[i]); int cnt=0; for(int i=0;i<n;i++) { for(int j=0;j<m;j++) { if(ma[i][j]=='.'&&!vis[i][j]) { num=0; dfs(i,j); // cout<<num<<endl; if(num>0)a[cnt++]={i,j,num}; } } } sort(a,a+cnt); int ans=0; // for(int i=0;i<cnt;i++) // { // cout<<a[i].x<<" "<<a[i].y<<" "<<a[i].water<<endl; // } for(int i=0;i<cnt-k;i++) { ans+=a[i].water; land(a[i].x,a[i].y); } printf("%d ",ans); for(int i=0;i<n;i++) { for(int j=0;j<m;j++) printf("%c",ma[i][j]); puts(""); } return 0; } /******************** 5 7 0 *.***** *..**** **..*** **.*.** ******* ********************/
E:题意:给你一张无向图,要求变成有向图,使得出度和入读相同的点最多
题解:根据欧拉路径的定义,只有起点和终点入度和出度不相同,其他都相同,那么我们可以对图中所有奇点(含奇数条边)连到虚拟节点上,然后因为奇点个数一定为偶数,那么这张图就变成欧拉回路了,我们可以用Hierholzer 算法来求解,最后删去虚拟节点连的边就好了
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include<bits/stdc++.h> #define fi first #define se second #define mp make_pair #define pb push_back #define pi acos(-1.0) #define ll long long #define mod 1000000007 #define C 0.5772156649 #define ls l,m,rt<<1 #define rs m+1,r,rt<<1|1 #define pil pair<int,ll> #define pii pair<int,int> #define ull unsigned long long #define base 1000000000000000000 #define fio ios::sync_with_stdio(false);cin.tie(0) using namespace std; const double g=10.0,eps=1e-12; const int N=200+10,maxn=2500+10,inf=0x3f3f3f3f; int G[N][N],cnt[N]; int in[N],out[N]; stack<pii>s; int n,m; void dfs(int u,int f) { // cout<<u<<" "<<f<<endl; for(int i=1;i<=n+1;i++) { if(G[u][i]) { G[u][i]--; G[i][u]--; dfs(i,u); } } if(f!=-1&&f!=n+1&&u!=n+1) { s.push(mp(f,u)); in[u]++; out[f]++; } } int main() { int t; scanf("%d",&t); while(t--) { scanf("%d%d",&n,&m); memset(in,0,sizeof in); memset(out,0,sizeof out); memset(G,0,sizeof G); memset(cnt,0,sizeof cnt); while(!s.empty())s.pop(); for(int i=0;i<m;i++) { int a,b; scanf("%d%d",&a,&b); G[a][b]++;G[b][a]++; cnt[a]^=1; cnt[b]^=1; } for(int i=1;i<=n;i++) { if(cnt[i]) { G[n+1][i]++; G[i][n+1]++; } } dfs(n+1,-1); while(s.size()<m) { for(int i=1;i<=n+1;i++) for(int j=1;j<=n+1;j++) if(G[i][j]) dfs(i,-1); } int ans=0; for(int i=1;i<=n;i++) if(in[i]==out[i]) ans++; printf("%d ",ans); while(!s.empty()) { printf("%d %d ",s.top().fi,s.top().se); s.pop(); } } return 0; } /******************** 1 6 6 1 2 2 3 3 1 4 5 5 6 4 6 ********************/
F:题意:给你一张无向图,要求找到一颗生成树,使得s,t两个节点的度不超过ds,dt
题解:刚开始想到的是先求出所有的桥,然后判断与s,t相连的桥个数有没有超过ds,dt,最后删掉多余的边就好了,但是我发现这个方法有个漏洞,就是当有两个不相交的连通图连向s或者t的时候,此时的删边操作会很复杂,所有放弃了这个做法,正解是先删掉s,t找联通块,然后联通块分成了三种,一种是只能和s连,一种是只能和t连,一种是st都能连,我们先连上前两种情况,对于第三种情况,我分了两种情况,看st有没有一条路,当st有一条路时,看,第三种联通块有几个,因为只有一个时,直接s,t连向它更优,其他的先连s,t,再连入度小的那一个,当s,t没有路时,第一个直接连s,连t,其他的连度小的那一个
=-=代码写的复杂了,应该是可以精简一点的
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include<bits/stdc++.h> #define fi first #define se second #define mp make_pair #define pb push_back #define pi acos(-1.0) #define ll long long #define mod 1000000007 #define C 0.5772156649 #define ls l,m,rt<<1 #define rs m+1,r,rt<<1|1 #define pil pair<int,ll> #define pii pair<int,int> #define ull unsigned long long #define base 1000000000000000000 #define fio ios::sync_with_stdio(false);cin.tie(0) using namespace std; const double g=10.0,eps=1e-12; const int N=200000+10,maxn=400000+10,inf=0x3f3f3f3f; pii p[maxn]; int father[N],belong[N]; vector<int>v[N],block[N]; bool vis[N]; int s,t,ds,dt; int n,m,cnt; int tos[N],tot[N]; int tosis[N],totis[N]; int Find(int x) { return x==father[x]?x:father[x]=Find(father[x]); } void dfs(int u) { if(u==s||u==t)return ; vis[u]=1; block[cnt].pb(u); belong[u]=cnt; for(int i=0;i<v[u].size();i++) { int x=v[u][i]; if(!vis[x])dfs(x); } } int main() { scanf("%d%d",&n,&m); for(int i=0;i<m;i++) { int a,b; scanf("%d%d",&a,&b); p[i]=mp(a,b); v[a].pb(b);v[b].pb(a); } scanf("%d%d%d%d",&s,&t,&ds,&dt); cnt=0; for(int i=1;i<=n;i++) { if(!vis[i]) { ++cnt,dfs(i); if(block[cnt].size()==0)cnt--; } father[i]=i; } // for(int i=1;i<=cnt;i++) // { // for(int j=0;j<block[i].size();j++) // { // printf("%d ",block[i][j]); // printf("++%d--",belong[block[i][j]]); // } // puts(""); // } vector<pii>ans; for(int i=0;i<m;i++) { int x=p[i].fi,y=p[i].se; if(belong[x]!=0&&belong[x]==belong[y]) { int fx=Find(x),fy=Find(y); if(fx!=fy) { father[fx]=fy; ans.pb(mp(x,y)); } } else if(belong[x]!=0&&belong[y]==0) { if(y==s) { tos[belong[x]]++; tosis[belong[x]]=x; } else { tot[belong[x]]++; totis[belong[x]]=x; } } else if(belong[y]!=0&&belong[x]==0) { if(x==s) { tos[belong[y]]++; tosis[belong[y]]=y; } else { tot[belong[y]]++; totis[belong[y]]=y; } } } for(int i=1;i<=cnt;i++) { if(tot[i]&&!tos[i]) { int x=totis[i],y=t; int fx=Find(x),fy=Find(y); if(fx!=fy) { father[fx]=fy; ans.pb(mp(x,y)); } } else if(!tot[i]&&tos[i]) { int x=tosis[i],y=s; int fx=Find(x),fy=Find(y); if(fx!=fy) { father[fx]=fy; ans.pb(mp(x,y)); } } } // for(int i=1;i<=cnt;i++) // { // printf("%d %d %d %d ",tot[i],totis[i],tos[i],tosis[i]); // } int des=0,det=0; for(int i=0;i<ans.size();i++) { int x=ans[i].fi,y=ans[i].se; if(x==s||y==s)des++; else if(x==t||y==t)det++; } if(des>ds||det>dt)return 0*puts("No"); bool hasst=0; // printf("%d++++%d ",s,t); for(int i=0;i<m;i++) { // printf("%d %d ",p[i].fi,p[i].se); if((p[i].fi==s&&p[i].se==t)||(p[i].fi==t&&p[i].se==s)) hasst=1; } int res=0; for(int i=1;i<=cnt;i++) if(tot[i]&&tos[i]) res++; if(hasst&&res!=1) { // puts("+++++"); if(Find(s)!=Find(t)) { father[Find(s)]=Find(t); ans.pb(mp(s,t)); des++,det++; if(des>ds||det>dt)return 0*puts("No"); } for(int i=1; i<=cnt; i++) { if(tot[i]&&tos[i]) { if(des<ds) { int x=tosis[i],y=s; int fx=Find(x),fy=Find(y); if(fx!=fy) { father[fx]=fy; ans.pb(mp(x,y)); } des++; } else if(det<dt) { int x=totis[i],y=t; int fx=Find(x),fy=Find(t); if(fx!=fy) { father[fx]=fy; ans.pb(mp(x,y)); } det++; } else return 0*puts("No"); } } } else { int one=0; for(int i=1;i<=cnt;i++) { if(tot[i]&&tos[i]) { if(!one) { int x=totis[i],y=t; int fx=Find(x),fy=Find(y); if(fx!=fy) { father[fx]=fy; ans.pb(mp(x,y)); } det++; x=tosis[i],y=s; fx=Find(x),fy=Find(y); if(fx!=fy) { father[fx]=fy; ans.pb(mp(x,y)); } des++; if(des>ds||det>dt)return 0*puts("No"); } else { if(des<ds) { int x=tosis[i],y=s; int fx=Find(x),fy=Find(y); if(fx!=fy) { father[fx]=fy; ans.pb(mp(x,y)); } des++; } else if(det<dt) { int x=totis[i],y=t; int fx=Find(x),fy=Find(t); if(fx!=fy) { father[fx]=fy; ans.pb(mp(x,y)); } det++; } else return 0*puts("No"); } one=1; } } } puts("Yes"); // printf("%d ",ans.size()); for(int i=0;i<ans.size();i++) printf("%d %d ",ans[i].fi,ans[i].se); return 0; } /******************** 10 10 1 3 10 3 6 1 2 7 1 7 1 9 9 5 2 10 10 8 4 3 9 5 2 4 ********************/