ICPC2017南寧站題解(A,E,F,H,I,J,L,M)
VP比賽時間:2020-07-23: 7 / 13 Rank: 35 / 228
VP通過:A,E,F,H,I,J,L
賽後補題:M
感想:這場對大數要求挺多(2道題F和L),我隊Java選手很給力。然後銀牌題大概是E和M(M那時候沒信心去挑戰畢竟在銀首,但是賽後補題發現是一個floyd+裸最大獨立集,還是簡單題。E是偏向思維的概率數學)。H是大模擬,I題是無腦dfs模擬。就這場和icpc2019南昌來說,我感覺銀牌圖論題可能要求並不是很高,要有信心去挑戰銀牌題吧。畢竟感覺銅牌圖論撐死就是生成樹和最短路了(真的嗎?)
A.Abiyoyo
第一簽到題,Anonytt,懶得說:
#include<bits/stdc++.h> #defineView Codell long long #define rep(i,a,n) for(int i=a;i<=n;i++) #define per(i,n,a) for(int i=n;i>=a;i--) #define endl '\n' #define eps 0.000000001 #define pb push_back #define mem(a,b) memset(a,b,sizeof(a)) #define IO ios::sync_with_stdio(false);cin.tie(0); using namespace std; const int INF=0x3f3f3f3f; const ll inf=0x3f3f3f3f3f3f3f3f; const int mod=1e9+7; const int maxn=1e5+5; int main(){ int T;cin>>T; while(T--){ int n;cin>>n; rep(i,1,n){ puts("Abiyoyo, Abiyoyo."); } rep(i,1,2){ puts("Abiyoyo, yo yoyo yo yoyo."); } } }
E. The Champion
銀牌題,Libm,我不會。
#include <bits/stdc++.h> #define ll unsigned long long #define endl '\n' using namespace std; double p; ll fa[65]; double cal(int r,ll k){ double ans=1; if(r==1){ if(k==1) ans=1; else ans=1-p; } else if(k<=fa[r-1]){ double cur=1; while(k<=fa[r-1]){ cur=cur*p; r--; if(r==1) break; } ans=(1-p)+p-cur+cur*cal(r,k); } else{ while(k>fa[r-1]){ k-=(fa[r-1]); r--; ans*=(1-p); if(r==1) break; } ans*=cal(r,k); } return ans; } double solve(int r,ll k){ double ans=1; if(r==1){ if(k==1) ans=p; else ans=1-p; return ans; } if(k==fa[r-1]+1){ for(int i=1;i<r;i++) ans*=p; ans*=(1-p); } else if(k<fa[r-1]+1){ for(int i=1;i<r;i++) ans*=p; double now=cal(r-1,k); ans=ans*(now*p+(1-now)*(1-p)); } else{ while(k>fa[r-1]+1){ k-=fa[r-1]; r--; ans*=(1-p); } ans*=solve(r,k); } return ans; } int main(){ ios::sync_with_stdio(false);cin.tie(0); int T;cin>>T; fa[0]=1; for(int i=1;i<=63;i++) fa[i]=fa[i-1]*2; while(T--){ int r; ll k; cin>>r>>k>>p; double ans=solve(r,k); printf("%.6lf\n",ans); } }View Code
F. The Chosen One
簽到java大數題,kele
import java.math.BigInteger; import java.util.Scanner; public class Main{ public static void main(String[] args){ Scanner input = new Scanner(System.in); int t = input.nextInt(); while (t > 0) { BigInteger m = input.nextBigInteger(); BigInteger ans = (new BigInteger("2")).pow(m.bitLength() - 1); System.out.println(ans); t--; } input.close(); } }View Code
H.The Game of Life
銅牌大模擬,我提供我(Anonytt)的寫法,因為是個無限大的圖,但是最多就321次衍生,所以實際上最終圖的大小是不會超過(2*321+n)*(2*321+m),為了方便所以我就把初始點全部行列+400。然後記錄當前是活著的點,把他們存在set裡,然後並對活著的周邊8個點的cnt進行統計。每次更新,用queue佇列來縮減時間。
#include<bits/stdc++.h> #define ll long long #define rep(i,a,n) for(int i=a;i<=n;i++) #define per(i,n,a) for(int i=n;i>=a;i--) #define endl '\n' #define eps 0.000000001 #define pb push_back #define mem(a,b) memset(a,b,sizeof(a)) #define IO ios::sync_with_stdio(false);cin.tie(0); using namespace std; const int INF=0x3f3f3f3f; const ll inf=0x3f3f3f3f3f3f3f3f; const int mod=1e9+7; const int maxn=1e5+5; int a[900][900],cnt[900][900]; int dx[9]={1,-1,0,0,1,1,-1,-1}; int dy[9]={0,0,1,-1,1,-1,1,-1}; int n,m; int main(){ int T;scanf("%d",&T); while(T--){ mem(a,0);mem(cnt,0); scanf("%d%d",&n,&m); int maxx=0,id=0; set<pair<int,int> >s; rep(i,1,n){ rep(j,1,m){ char xx;cin>>xx; if(xx=='#'){ int u=i+400,v=j+400; a[u][v]=1;++maxx; rep(o,0,7){ int x=u+dx[o],y=v+dy[o]; cnt[x][y]+=1; s.insert({x,y}); } s.insert({u,v}); } else a[i+400][j+400]=0; } } int c; rep(t,1,321){ int cur=0; queue<pair<int,int> >q; for(auto it:s){ int x=it.first,y=it.second; if(cnt[x][y]==3&&!a[x][y]) {a[x][y]=1;++cur;q.push({x,y});} else if((cnt[x][y]==2&&a[x][y])||(cnt[x][y]==3&&a[x][y])) {a[x][y]=1;++cur;q.push({x,y});} else if((cnt[x][y]<=1&&a[x][y])||(cnt[x][y]>=4&&a[x][y])) {a[x][y]=0;} cnt[x][y]=0; } if(cur>maxx) {maxx=cur,id=t;} if(t==321) c=cur; s.clear(); if(t<321){ while(!q.empty()){ auto now=q.front();q.pop(); int x=now.first,y=now.second; s.insert({x,y}); } queue<pair<int,int> >que; for(auto it:s){ int xx=it.first,yy=it.second; rep(o,0,7){ int x=xx+dx[o],y=yy+dy[o]; cnt[x][y]+=1;que.push({x,y}); } } while(!que.empty()){ auto now=que.front();que.pop(); int x=now.first,y=now.second; s.insert({x,y}); } } } cout<<id<<" "<<maxx<<" "<<c<<endl; } }View Code
I.Rake It In
銅牌無腦暴力dfs。Anonytt,時間複雜度大概=200*pow(9,6)≈1e8,剛好能擦過,所以就無腦暴力吧
#include<bits/stdc++.h> #define ll long long #define rep(i,a,n) for(int i=a;i<=n;i++) #define per(i,n,a) for(int i=n;i>=a;i--) #define endl '\n' #define eps 0.000000001 #define pb push_back #define mem(a,b) memset(a,b,sizeof(a)) #define IO ios::sync_with_stdio(false);cin.tie(0); using namespace std; const int INF=0x3f3f3f3f; const ll inf=0x3f3f3f3f3f3f3f3f; const int mod=1e9+7; const int maxn=1e5+5; int a[5][5],k; int find(int x,int y){ int res=0; res+=a[x][y]+a[x+1][y]+a[x][y+1]+a[x+1][y+1]; return res; } void rot(int x,int y){ int temp=a[x][y]; a[x][y]=a[x][y+1]; a[x][y+1]=a[x+1][y+1]; a[x+1][y+1]=a[x+1][y]; a[x+1][y]=temp; } void back(int x,int y){ int temp=a[x][y]; a[x][y]=a[x+1][y]; a[x+1][y]=a[x+1][y+1]; a[x+1][y+1]=a[x][y+1]; a[x][y+1]=temp; } int dfs(int t){ if(t==2*k){ int ans=INF,x,y; rep(i,1,3){ rep(j,1,3){ ans=min(ans,find(i,j)); } } return ans; } else{ if(t%2==1){ int ans=0,x,y; rep(i,1,3){ rep(j,1,3){ rot(i,j); ans=max(ans,find(i,j)+dfs(t+1)); back(i,j); } } return ans; } if(t%2==0){ int ans=INF,x,y; rep(i,1,3){ rep(j,1,3){ rot(i,j); ans=min(ans,find(i,j)+dfs(t+1)); back(i,j); } } return ans; } } } int main(){ int T;scanf("%d",&T); while(T--){ scanf("%d",&k); rep(i,1,4){ rep(j,1,4){ scanf("%d",&a[i][j]); } } cout<<dfs(1)<<endl; } }View Code
J. Rearrangement
簽到,Anonytt
#include<bits/stdc++.h> #define ll long long #define rep(i,a,n) for(int i=a;i<=n;i++) #define per(i,n,a) for(int i=n;i>=a;i--) #define endl '\n' #define eps 0.000000001 #define pb push_back #define mem(a,b) memset(a,b,sizeof(a)) #define IO ios::sync_with_stdio(false);cin.tie(0); using namespace std; const int INF=0x3f3f3f3f; const ll inf=0x3f3f3f3f3f3f3f3f; const int mod=1e9+7; const int maxn=1e5+5; int a[2*maxn]; int main(){ int T;scanf("%d",&T); while(T--){ int n;scanf("%d",&n); int cnt1=0,cnt2=0,cnt3=0; rep(i,1,2*n){ scanf("%d",&a[i]); if(a[i]%3==0) cnt3++; if(a[i]%3==1) cnt1++; if(a[i]%3==2) cnt2++; } if(cnt3>n) {puts("NO");continue;} if(cnt3==n){puts("YES");continue;} else if(cnt3==0){ if(cnt1&&cnt2) puts("NO"); else puts("YES"); } else if(cnt3==1){ if(cnt1&&cnt2) puts("NO"); else puts("YES"); } else if(cnt3==2){ if(cnt1%2==0&&cnt2%2==0){puts("NO");continue;} else puts("YES"); } else puts("YES"); } }View Code
L. Twice Equation
大數java+板子,kele
import java.math.BigInteger; import java.util.Scanner; public class Main{ public static void main(String[] args){ Scanner input = new Scanner(System.in); int t = input.nextInt(); BigInteger[] a = new BigInteger[1000]; a[0] = BigInteger.ZERO; a[1] = BigInteger.valueOf(3); BigInteger ke = new BigInteger("6"); BigInteger le = new BigInteger("2"); for(int i = 2; i <= 400; i++){ a[i] = ((a[i - 1].multiply(ke)).subtract(a[i - 2])).add(le); // System.out.println(a[i]); } for(int i = 0; i < t; i++) { boolean flag = false; BigInteger L = input.nextBigInteger(); for(int j = 0; j <= 400; j++){ if(a[j].compareTo(L) >= 0){ System.out.println(a[j]); flag = true; break; } } if(!flag) System.out.println(-1); } input.close(); } }View Code
M.The Maximum Unreachable Node Set
(賽後通過Anonytt),其實就是一個最大獨立集的問題,不過需要之前用floyd轉化,其實看出最大獨立集不難,關鍵是想到floyd轉化
#include<bits/stdc++.h> #define ll long long #define rep(i,a,n) for(int i=a;i<=n;i++) #define per(i,n,a) for(int i=n;i>=a;i--) #define endl '\n' #define eps 0.000000001 #define pb push_back #define mem(a,b) memset(a,b,sizeof(a)) #define IO ios::sync_with_stdio(false);cin.tie(0); using namespace std; const int INF=0x3f3f3f3f; const ll inf=0x3f3f3f3f3f3f3f3f; const int mod=1e9+7; const int maxn=1e5+5; int n,m,line[505][505],used[505],match[505]; int find(int x){ rep(i,1,n){ if(!used[i]&&line[x][i]){ used[i]=true; if(match[i]==0||find(match[i])){ match[i]=x; return true; } } } return false; } int main(){ int T;scanf("%d",&T); while(T--){ scanf("%d%d",&n,&m); mem(line,0);mem(match,0); rep(i,1,m){ int u,v;scanf("%d%d",&u,&v); line[u][v]=1; } rep(k,1,n){ rep(i,1,n){ rep(j,1,n){ if(line[i][k]&&line[k][j]) line[i][j]=1; } } } int ans=0; rep(i,1,n){ mem(used,0); if(find(i)) ++ans; } printf("%d\n",n-ans); } }View Code
再接再厲啊,希望現場icpc區域賽能有銀牌qwq