Codeforces Round #375 (Div. 2)
阿新 • • 發佈:2018-01-15
eve find names eps push_back include std truct pla
昨天打的,補了一天半才補完。。。
A:水題
#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> #defineApii 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\n",ans); return 0; } /******************** ********************/
B:也很水,模擬即可
#include<bits/stdc++.h> #define fi first #define se second #define mp make_pair #defineBpb 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<<"\n"; return 0; } /******************** ********************/
C:題意:給一些n個數,要改變最小的次數來使得1到m出現最少的次數最大
題解:肯定n/m就是次數,然後依次找需要改變的地方填充即可
#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\n",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\n",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; } /******************** ********************/C
D:傻逼題,爆搜即可(當時爆搜寫爆了,然後mle。。。。原來遞歸太深也是會mle的)
#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\n",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 *.***** *..**** **..*** **.*.** ******* ********************/D
E:題意:給你一張無向圖,要求變成有向圖,使得出度和入讀相同的點最多
題解:根據歐拉路徑的定義,只有起點和終點入度和出度不相同,其他都相同,那麽我們可以對圖中所有奇點(含奇數條邊)連到虛擬節點上,然後因為奇點個數一定為偶數,那麽這張圖就變成歐拉回路了,我們可以用Hierholzer 算法來求解,最後刪去虛擬節點連的邊就好了
#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\n",ans); while(!s.empty()) { printf("%d %d\n",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 ********************/E
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,其他的連度小的那一個
=-=代碼寫的復雜了,應該是可以精簡一點的
#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\n",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\n",s,t); for(int i=0;i<m;i++) { // printf("%d %d\n",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\n",ans.size()); for(int i=0;i<ans.size();i++) printf("%d %d\n",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 ********************/F
Codeforces Round #375 (Div. 2)