天梯賽2:
7-12 這是二叉搜尋樹嗎?
在滿足題意的前提下從前後分別往中間走模擬二叉樹的建立即可。
// /l、 //(゚、 。 7 // l、 ~ヽ // じしf_, )ノ // 不要放棄!貓貓會為你加油! #include <bits/stdc++.h> #define endl '\n' #define int long long using namespace std; const int N = 2e5+10 , M = 1e6+10 ; int k[N]; int n,st=0; vector<int> ans; void build(int l,int r) { if(l>r) return ; int i = l+1 , j=r; if(st) { while(i<=r && k[i]>=k[l]) i++; while(j>l && k[j]<k[l]) j--; i-- , j++; } else { while(i<=r && k[i]<k[l]) i++; while(j>l && k[j]>=k[l]) j--; i-- , j++; } if(j-i!=1) return ; build(l+1,i); build(j,r); ans.push_back(k[l]); } void solve() { cin >> n; for(int i=1;i<=n;i++) cin >> k[i]; build(1,n); if(ans.size()==n) { cout << "YES" << endl; for(int i=1;i<=n;i++) cout << ans[i-1] << " \n"[i==n]; return ; } ans.clear(); st^=1; build(1,n); if(ans.size()==n) { cout << "YES" << endl; for(int i=1;i<=n;i++) cout << ans[i-1] << " \n"[i==n]; return ; } cout << "NO" << endl; } signed main() { ios::sync_with_stdio(0); cin.tie(0) , cout.tie(0); int T = 1; // cin >> T ; while(T--) solve(); return 0; }
7-13 腫瘤診斷
三維bfs即可。(賽時寫的dfs爆棧空間導致re,好似了這下)
// /l、 //(゚、 。 7 // l、 ~ヽ // じしf_, )ノ // 不要放棄!貓貓會為你加油! #include <bits/stdc++.h> #define endl '\n' #define int long long using namespace std; const int N = 2e5+10 , M = 1e6+10 ; int n,m,l,t; int k[70][1310][130]; bool vis[70][1310][130]; struct node { int l,x,y; }; int dx[7]={0,1,-1,0,0,0,0}; int dy[7]={0,0,0,1,-1,0,0}; int dz[7]={0,0,0,0,0,1,-1}; int bfs(int a,int b,int c) { int cnt=1; queue<node> q; q.push({a,b,c}); vis[a][b][c]=1; while(q.size()) { auto [z,x,y] = q.front(); q.pop(); for(int i=1;i<=6;i++) { int xt = dx[i]+x , yt = dy[i]+y , zt = dz[i]+z; if(xt>=1 && xt<=n && yt>=1 && yt<=m && zt>=1 && zt<=l && !vis[zt][xt][yt] && k[zt][xt][yt]==1) { cnt++; vis[zt][xt][yt]=1; q.push({zt,xt,yt}); } } } return cnt; } void solve() { cin >> n >> m >> l >> t; for(int x=1;x<=l;x++) { for(int i=1;i<=n;i++) { for(int j=1;j<=m;j++) cin >> k[x][i][j]; } } int ans=0; for(int x=1;x<=l;x++) { for(int i=1;i<=n;i++) { for(int j=1;j<=m;j++) { if(k[x][i][j]==1 && !vis[x][i][j]) { int cnt = bfs(x,i,j); if(cnt>=t) ans+=cnt; cnt=0; } } } } cout << ans << endl; } signed main() { ios::sync_with_stdio(0); cin.tie(0) , cout.tie(0); int T = 1; // cin >> T ; while(T--) solve(); return 0; }
7-15 特殊堆疊
multiset(自定義排序)維護對頂堆。也可以權值樹狀陣列加二分。
這裡用的二分維護vector的增加和刪除操作。
// /l、 //(゚、 。 7 // l、 ~ヽ // じしf_, )ノ // 不要放棄!貓貓會為你加油! #include <bits/stdc++.h> #define endl '\n' #define int long long using namespace std; const int N = 2e5+10 , M = 1e6+10 ; int k[N]; void solve() { int n; cin >> n; int idx=0; vector<int> ans; while(n--) { string s; cin >> s; if(s=="Pop") { if(idx==0) { cout << "Invalid" << endl; } else { int x = k[idx--]; ans.erase(lower_bound(ans.begin() , ans.end() , x)); cout << x << endl; } } else if(s=="PeekMedian") { if(idx==0) { cout << "Invalid" << endl; } else { int x = (idx+1)/2-1; cout << ans[x] << endl; } } else { int x; cin >> x; k[++idx]=x; ans.insert(lower_bound(ans.begin() , ans.end() , x) , x); } } } signed main() { ios::sync_with_stdio(0); cin.tie(0) , cout.tie(0); int T = 1; // cin >> T ; while(T--) solve(); return 0; }
div4:
D:完全揹包板子改一下
// /l、 //(゚、 。 7 // l、 ~ヽ // じしf_, )ノ // 不要放棄!貓貓會為你加油! #include <bits/stdc++.h> #define endl '\n' #define int long long using namespace std; const int N = 2e5+10 , M = 1e6+10 ; int f[N]; vector<int> v; void init() { for(int i=0;i<(1<<5);i++) { int x=0; for(int j=4;j>=0;j--) { if((i>>j)&1) x = x*10+1; else x=x*10; } f[x]=1; if(x) v.push_back(x); } f[100000]=1; for(auto & t : v) { for(int j=t;j<=100000;j++) { if(j%t==0) { int w = j/t; if(f[w]) f[j]=1; } } } } void solve() { int n; cin >> n; cout << (f[n] ? "YES" : "NO") << endl; } signed main() { ios::sync_with_stdio(0); cin.tie(0) , cout.tie(0); int T = 1; init(); cin >> T ; while(T--) solve(); return 0; }
E:列舉字串長度檢查即可
// /l、 //(゚、 。 7 // l、 ~ヽ // じしf_, )ノ // 不要放棄!貓貓會為你加油! #include <bits/stdc++.h> #define endl '\n' #define int long long using namespace std; const int N = 2e5+10 , M = 1e6+10 ; void solve() { int n; cin >> n; string s; cin >> s; s = ' ' + s; for(int k=n;k>=1;k--) { if(n%k) continue; int cnt=0 , len=n/k; for(int i=1,j=1;i<=n;i++) { if(s[j]!=s[i]) cnt++; if(j==len) j=1; else j++; } string d = s + ' '; reverse(d.begin() , d.end()); int res=0; for(int i=1,j=1;i<=n;i++) { if(d[j]!=d[i]) res++; if(j==len) j=1; else j++; } if(cnt<2 || res<2) { cout << len << endl; return ; } } } signed main() { ios::sync_with_stdio(0); cin.tie(0) , cout.tie(0); int T = 1; cin >> T ; while(T--) solve(); return 0; }
F:兩種寫法:
一:分類討論,並且必須滿足a+1 == c。
二:bfs維護層數,先a在b最後c,這種更好寫。
// /l、 //(゚、 。 7 // l、 ~ヽ // じしf_, )ノ // 不要放棄!貓貓會為你加油! #include <bits/stdc++.h> #define endl '\n' #define int long long using namespace std; const int N = 2e5+10 , M = 1e6+10 ; void solve() { int a,b,c; cin >> a >> b >> c; if(!a && !b) { if(c==1) cout << 0 << endl; else cout << -1 << endl; } else if(!a && !c) cout << -1 << endl; else if(!b && !c) cout << -1 << endl; else if(!c) cout << -1 << endl; else if(!a) { if(c==1) cout << b << endl; else cout << -1 << endl; } else if(!b) { if(a+1!=c) cout << -1 << endl; else { int cnt=0; for(int i=0;;i++) { int x = (1<<i); if(cnt+x>=a) { cout << i+1 << endl; return ; } else cnt+=x; } } } else { if(a+1!=c) { cout << -1 << endl; return ; } int ans=0; int cnt=0 , w; for(int i=0;;i++) { int x = (1<<i); if(cnt+x>a) { ans=i; a-=cnt; w=x; break; } else cnt+=x; } if(a+b<=w) { cout << ans+1 << endl; return ; } b-=w-a; int d = (w-a)+a*2; int res=b/d; if(b%d) res++; cout << ans+res+1 << endl; } } signed main() { ios::sync_with_stdio(0); cin.tie(0) , cout.tie(0); int T = 1; cin >> T ; while(T--) solve(); return 0; }
G:很經典的狀壓DP
初始化每個點作為起點的情況。
然後二進位制列舉每一種狀態,若當前狀態被標記,記錄一下答案,更新當前狀態可以到達的其他的狀態。
比如當前狀態f[i][j],現在列舉到一個點k,若j可以到k並且k這個點當前狀態沒有標記k點,就考慮更新k點。
// /l、 //(゚、 。 7 // l、 ~ヽ // じしf_, )ノ // 不要放棄!貓貓會為你加油! #include <bits/stdc++.h> #define endl '\n' #define int long long using namespace std; const int N = 2e5+10 , M = 1e6+10 ; void solve() { int n; cin >> n; vector<pair<string , string>> s(n+10); vector<vector<int>> d(n+10,vector<int>(n+10)); for(int i=0;i<n;i++) cin >> s[i].first >> s[i].second; for(int i=0;i<n;i++) { for(int j=0;j<n;j++) { if(i==j) continue; if(s[i].first==s[j].first || s[i].second==s[j].second) d[i][j]=d[j][i]=1; } } vector<vector<int>> f((1<<n)+10,vector<int>(n+10)); for(int i=0;i<n;i++) f[1<<i][i]=1; int ans=0; for(int i=1;i<(1<<n);i++) { for(int j=0;j<n;j++) { if(f[i][j]) { int res=0; for(int k=0;k<n;k++) { if((i>>k)&1) res++; } ans=max(ans,res); for(int k=0;k<n;k++) { if(((i>>k)&1)==0 && d[j][k]) { f[i|(1<<k)][k]=1; } } } } } cout << n-ans << endl; } signed main() { ios::sync_with_stdio(0); cin.tie(0) , cout.tie(0); int T = 1; cin >> T ; while(T--) solve(); return 0; }
天梯賽3:
7-14 天梯地圖
Dijkstra維護兩個鍵值即可。
// /l、 //(゚、 。 7 // l、 ~ヽ // じしf_, )ノ // 不要放棄!貓貓會為你加油! #include <bits/stdc++.h> #define endl '\n' using namespace std; const int N = 510 , M = 1e6+10 ; struct node { int x,y,z; bool operator < (const node & a) const { return x > a.x; } }; int n,m,st,en; int fl[N],ft[N]; int disl[N],dist[N]; int L[N],T[N]; bool visl[N],vist[N]; vector<int> ansl,anst; vector<node> vl[N],vt[N]; void bfsl(int x) { priority_queue<node> q; memset(disl , 0x3f , sizeof disl); memset(T , 0x3f , sizeof T); q.push({0,0,x}); disl[x]=0 , T[x]=0; while(q.size()) { int t = q.top().z; q.pop(); if(visl[t]) continue; visl[t]=1; for(auto & [u,w,d] : vl[t]) { if(disl[u] > disl[t] + w) { disl[u] = disl[t] + w; T[u]=T[t]+1; fl[u]=t; q.push({disl[u],T[u],u}); } else if(disl[u] == disl[t] + w) { if(T[u]>T[t]+1) { T[u] = T[t]+1 , fl[u]=t; q.push({disl[u],T[u],u}); } } } } } void bfst(int x) { priority_queue<node> q; memset(dist , 0x3f , sizeof dist); memset(L , 0x3f , sizeof L); q.push({0,0,x}); dist[x]=0 , L[x]=0; while(q.size()) { int t = q.top().z; q.pop(); if(vist[t]) continue; vist[t]=1; for(auto & [u,w,d] : vt[t]) { if(dist[u] > dist[t] + w) { dist[u] = dist[t] + w; L[u]=L[t]+d; ft[u]=t; q.push({dist[u],L[u],u}); } else if(dist[u] == dist[t] + w) { if(L[u]>L[t]+d) { L[u] = L[t]+d , ft[u]=t; q.push({dist[u],L[u],u}); } } } } } void solve() { cin >> n>> m; for(int i=1;i<=m;i++) { int v1,v2,way,l,t; cin >> v1 >> v2 >> way >> l >> t; vl[v1].push_back({v2,l,t}); vt[v1].push_back({v2,t,l}); if(way==0) { vl[v2].push_back({v1,l,t}); vt[v2].push_back({v1,t,l}); } } cin >> st >> en; fl[st]=-1 , ft[st]=-1; bfsl(st); bfst(st); int d = en; while(fl[d]!=-1) ansl.push_back(d) , d = fl[d]; ansl.push_back(st); d = en; while(ft[d]!=-1) anst.push_back(d) , d = ft[d]; anst.push_back(st); reverse(ansl.begin() , ansl.end()); reverse(anst.begin() , anst.end()); // cout << "ansl: " << endl; // for(auto & t : ansl) cout << t << ' '; // cout << endl; // // cout << "anst: " << endl; // for(auto & t : anst) cout << t << ' '; // cout << endl; // // cout << "dist: " << endl; // for(int i=0;i<n;i++) cout << dist[i] << " \n"[i==n-1]; if(ansl==anst) { cout << "Time = " << dist[en] << "; Distance = " << disl[en] << ": "; for(int i=0;i<ansl.size();i++) { cout << ansl[i]; if(i==ansl.size()-1) cout << endl; else cout << " => "; } } else { cout << "Time = " << dist[en] << ": "; for(int i=0;i<anst.size();i++) { cout << anst[i]; if(i==anst.size()-1) cout << endl; else cout << " => "; } cout << "Distance = " << disl[en] << ": "; for(int i=0;i<ansl.size();i++) { cout << ansl[i]; if(i==ansl.size()-1) cout << endl; else cout << " => "; } } } signed main() { ios::sync_with_stdio(0); cin.tie(0) , cout.tie(0); int T = 1; // cin >> T ; while(T--) solve(); return 0; }