今天偶然發現天梯賽的代碼還保存著,于是決定寫下這篇題解,也算是復盤一下了
L1本來是打算寫的穩妥點,最后在L1-6又想省時間,又忘記了insert,replace這些方法怎么用,也不想花時間寫一個文件測試,最后用了兩個vector<int>a,b每次操作來回傳數組的元素,以為實現起來很方便,最后反而寫了個170行的屎山代碼,花了一個多小時的時間debug最后還只拿了5分,屬于是左右腦互博了...
L2的話,L2-2寫著寫著把無解-1忘了?L2-4少了一些邊界條件
L3 最后15分鐘發現L3-3很多人拿了16分,于是火急火燎寫了一個暴力,怒拿1分,賽后看代碼才發現把同一種情況下的乘法寫成加法了
欲速則不達,以后做事還是慢慢來,先把基礎打扎實。接下來要準備考研了,就當這是個提醒吧。
L1-105 珍惜生命
#include<bits/stdc++.h>
using namespace std;
#define _rep(i,a,b) for(int i=(int)(a);i<=(int)b;++i)
#define IOS ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
int n,m,k;
const int N=1e6+10;
void solve()
{cout<<"Always code as if the guy who ends up maintaining your code will be a violent psychopath who knows where you live.";
}
signed main()
{IOS;int T=1;
// cin>>T;while(T--)solve();return 0;
}
L1-106 偷感好重
#include<bits/stdc++.h>
using namespace std;
#define _rep(i,a,b) for(int i=(int)(a);i<=(int)b;++i)
#define IOS ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
int n,m,k;
const int N=1e6+10;
void solve()
{cin>>n>>m>>k;cout<<n+m+k<<'\n';
}
signed main()
{IOS;int T=1;
// cin>>T;while(T--)solve();return 0;
}
L1-107 高溫補貼
按照題意模擬
#include<bits/stdc++.h>
using namespace std;
#define _rep(i,a,b) for(int i=(int)(a);i<=(int)b;++i)
#define IOS ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
int n,m,k;
const int N=1e6+10;
void solve()
{int t,s,t1;cin>>t>>s>>t1;if(t>=35&&s&&t1>=33)cout<<"Bu Tie\n"<<t;else if(t>=35&&!s&&t1>=33)cout<<"Shi Nei\n"<<t;else if(s)cout<<"Bu Re\n"<<t1;else cout<<"Shu Shi\n"<<t1;
}
signed main()
{IOS;int T=1;
// cin>>T;while(T--)solve();return 0;
}
L1-108 零頭就抹了吧
找到2^i中第一個大于付的錢的i,然后輸出2^(i-1)
#include<bits/stdc++.h>
using namespace std;
#define _rep(i,a,b) for(int i=(int)(a);i<=(int)b;++i)
#define IOS ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
#define pb push_back
#define pp pop_back()
#define fi first
#define se second
typedef pair<int,int> PII;
typedef pair<double,double> PDD;
int n,m,k;
void solve()
{cin>>n;int i=0;while((1<<i)<=n){i++;}cout<<(1<<(i-1));
}
signed main()
{IOS;int T=1;
// cin>>T;while(T--)solve();return 0;
}
L1-109 這是字符串題
#include<bits/stdc++.h>
using namespace std;
#define _rep(i,a,b) for(int i=(int)(a);i<=(int)b;++i)
#define IOS ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
#define pb push_back
#define pp pop_back()
#define fi first
#define se second
typedef pair<int,int> PII;
typedef pair<double,double> PDD;
int n,m,k;
const int N=1e6+10;
int a[N],b[N];
void solve()
{string s;cin>>s;_rep(i,0,25){cin>>a[i];}int res=0;for(auto i:s){res+=a[i-'a'];b[i-'a']++;}_rep(i,0,25){cout<<b[i]<<" \n"[i==25];}cout<<res<<endl;
}
signed main()
{IOS;int T=1;
// cin>>T;while(T--)solve();return 0;
}
L1-110 這不是字符串題
用一個自增的cnt和vector<int>a,b,cnt為奇數就把a的東西存到b去,反之
#include<bits/stdc++.h>
using namespace std;
#define _rep(i,a,b) for(int i=(int)(a);i<=(int)b;++i)
#define IOS ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
#define pb push_back
#define pp pop_back()
#define fi first
#define se second
typedef pair<int,int> PII;
typedef pair<double,double> PDD;
int n,m,k;
const int N=1e6+10;
vector<int>a,b;
int cnt;
void solve()
{cin>>n>>m;_rep(i,1,n){int x;cin>>x;a.pb(x);}while(m--){cnt++;int op;cin>>op;if(op==1){int l1,l2;cin>>l1;vector<int>c;while(l1--){int x;cin>>x;c.pb(x);}cin>>l2;vector<int>d;while(l2--){int x;cin>>x;d.pb(x);}int idx=-1;if(cnt&1){for(int i=0;i<(int)a.size();i++){if(i+(int)c.size()>(int)a.size())break;bool bl=true;for(int j=0,k=i;j<(int)c.size();j++,k++){if(c[j]!=a[k]){bl=false;break;}}if(bl){idx=i;break;}}}else{for(int i=0;i<(int)b.size();i++){if(i+(int)c.size()>(int)b.size())break;bool bl=true;for(int j=0,k=i;j<(int)c.size();j++,k++){if(c[j]!=b[k]){bl=false;break;}}if(bl){idx=i;break;}}}if(idx!=-1){if(cnt&1){bool bl=false;for(int i=0;i<(int)a.size();i++){if(idx<=i&&i<=idx+((int)c.size())-1){if(!bl){for(auto k:d){b.pb(k);}bl=true;}}else b.pb(a[i]);}a.clear();}else {bool bl=false;for(int i=0;i<(int)b.size();i++){if(idx<=i&&i<=idx+((int)c.size())-1){if(!bl){for(auto k:d){a.pb(k);}bl=true;}}else a.pb(b[i]);}b.clear();}}else cnt++;}else if(op==2){if(cnt&1){for(int i=0;i<(int)a.size();i++){if(!i)b.pb(a[i]);else {if((a[i]+a[i-1])%2==0){b.pb((a[i]+a[i-1])/2);}b.pb(a[i]);}}a.clear();}else {for(int i=0;i<(int)b.size();i++){if(!i)a.pb(b[i]);else {if((b[i]+b[i-1])%2==0){a.pb((b[i]+b[i-1])/2);}a.pb(b[i]);}}b.clear();}}else {int l,r;cin>>l>>r;l--,r--;if(cnt&1){for(int i=0;i<(int)a.size();i++){if(l<=i&&i<=r){b.pb(a[l+r-i]);}else b.pb(a[i]);}a.clear();}else{for(int i=0;i<(int)b.size();i++){if(l<=i&&i<=r){a.pb(b[l+r-i]);}else a.pb(b[i]);}b.clear();}}}if(cnt%2==0){for(int i=0;i<(int)a.size();i++){cout<<a[i]<<" \n"[i==(int)a.size()-1];}}else {for(int i=0;i<(int)b.size();i++){cout<<b[i]<<" \n"[i==(int)b.size()-1];}}
}
signed main()
{IOS;int T=1;
// cin>>T;while(T--)solve();return 0;
}
L1-111 大冪數
可以發現指數k(我的代碼中是m)最大從31開始向下遞減,每次暴力判斷的時間復雜度是根號級別的,所以直接枚舉指數然后判斷即可
#include<bits/stdc++.h>
using namespace std;
#define int long long
#define _rep(i,a,b) for(int i=(int)(a);i<=(int)b;++i)
#define IOS ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
#define pb push_back
#define pp pop_back()
#define fi first
#define se second
typedef pair<int,int> PII;
typedef pair<double,double> PDD;
int n,m,k;
const int N=1e6+10;
int qmi(int a,int b){int res=1;while(b){if(b&1)res=res*a;a=a*a;b>>=1;}return res;
}
vector<int>a,b;
int cnt;
int check(int k,int sum){int s=0;for(int i=1;;i++){s+=qmi(i,k);if(s==sum)return i;if(s>sum)return -1; }
}
void solve()
{cin>>n;int m=31;bool bl=false;while(m!=0){int t=check(m,n);if(t!=-1){_rep(i,1,t){cout<<i<<"^"<<m<<"+\n"[i==t];}bl=true;break;}m--;}if(!bl)cout<<"Impossible for "<<n<<".";
}
signed main()
{IOS;int T=1;
// cin>>T;while(T--)solve();return 0;
}
L1-112 現代戰爭
用一個優先隊列每次彈出最大值,然后彈出過后的話就把坐標的行列標記為使用過,于是每一輪彈出坐標,直到那個彈出的坐標的行列沒有被使用過,那個坐標就是這一輪要被刪除的坐標
#include<bits/stdc++.h>
using namespace std;
#define _rep(i,a,b) for(int i=(int)(a);i<=(int)b;++i)
#define IOS ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
#define pb push_back
#define pp pop_back()
#define fi first
#define se second
typedef pair<int,int> PII;
typedef pair<double,double> PDD;
int n,m,k;
const int N=1e6+10;
int g[1010][1010];
bool st[1010][1010];
struct aa{int i,j,w;
};
struct cmp{bool operator()(aa a,aa b){return a.w<b.w;}
};
void solve()
{int n,m,k;cin>>n>>m>>k;priority_queue<aa,vector<aa>,cmp>p;_rep(i,1,n){_rep(j,1,m){int x;cin>>x;g[i][j]=x;p.push({i,j,x});}}while(k--){auto t=p.top();while(1){p.pop();if(!st[t.i][t.j])break;t=p.top();}for(int j=1;j<=n;j++){st[j][t.j]=true;}for(int j=1;j<=m;j++){st[t.i][j]=true;}}for(int i=1;i<=n;i++){bool bl=false;for(int j=1;j<=m;j++){if(st[i][j])continue;if(bl)cout<<" ";bl=true;cout<<g[i][j];}if(bl)cout<<'\n';}
}
signed main()
{IOS;int T=1;
// cin>>T;while(T--)solve();return 0;
}
L2-053 算式拆解
一個棧儲存碰到的所有字母,遇到')'就一直彈出直到遇到‘(’,在這途中彈出的字符就是這一行的算式
#include<bits/stdc++.h>
using namespace std;
#define _rep(i,a,b) for(int i=(int)(a);i<=(int)b;++i)
#define IOS ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
#define pb push_back
#define pp pop_back()
#define fi first
#define se second
#define all(x) (x).begin(),(x).end()
typedef pair<int,int> PII;
typedef pair<double,double> PDD;
int n,m,k;
const int N=1e6+10;
void solve()
{string s;cin>>s;vector<char>v;for(auto i:s){if(i==')'){vector<char>now;while(v.back()!='('){now.pb(v.back());v.pp;}v.pp;reverse(all(now));for(int i=0;i<(int)now.size();i++){cout<<now[i];}cout<<'\n';}else v.pb(i);}
}
signed main()
{IOS;int T=1;
// cin>>T;while(T--)solve();return 0;
}
L2-054 三點共線
枚舉前兩維(y=0,1),判斷第三維(y=2),把y=2時的x存到數組里,不過要注意存的時候防止出現負數,最壞情況下,第一維1e6,第二維-1e6,為了防止負數所以第三維要整體+3e6
#include<bits/stdc++.h>
using namespace std;
#define int long long
#define double long double
#define _rep(i,a,b) for(int i=(int)(a);i<=(int)b;++i)
#define IOS ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
#define pb push_back
#define pp pop_back()
#define fi first
#define se second
#define all(x) (x).begin(),(x).end()
#define laile cout<<"laile"<<endl;
typedef pair<int,int> PII;
typedef pair<double,double> PDD;
int n,m,k;
const int N=1e6+10,INF=4e18;
vector<int>q[4];
bool st[4][N];
struct aa{int a,b,c;
};
bool cmp(aa a,aa b){if(a.b!=b.b)return a.b<b.b;return a.a<b.a;
}
vector<aa>res;
int has[6000001];
void solve()
{cin>>n;_rep(i,1,n){int x,y;cin>>x>>y;y++;if(y==3)has[x+3000010]++;else q[y].pb(x);}if(q[1].size())sort(all(q[1]));if(q[2].size())sort(all(q[2]));for(int i=0;i<(int)q[1].size();i++){int pre=0;if(i&&q[1][i]==q[1][i-1])continue;for(int j=0;j<(int)q[2].size();j++){if(j&&q[2][j]==q[2][j-1])continue;int sub=q[2][j]-q[1][i];if(has[q[2][j]+sub+3000010])res.pb({q[1][i],q[1][i]+sub,q[1][i]+2*sub});}}aa pre={-INF,-INF,-INF};sort(all(res),cmp);if(!res.size())cout<<"-1\n";else{for(auto i:res){if(pre.a!=i.a||pre.b!=i.b||pre.c!=i.c){cout<<"["<<i.a<<", 0] ["<<i.b<<", 1] ["<<i.c<<", 2]\n";}pre=i;}}
}
signed main()
{IOS;int T=1;
// cin>>T;while(T--)solve();return 0;
}
L2-055 胖達的山頭
最小區間覆蓋問題?
先給區間排序,用multset存每個區間的右端點,每次找到multset中第一個大于當前區間左端點的點,然后把這個點替換成這個新的點,如果沒找到就直接插入這個區間的右端點,最后multiset的元素個數就是最終答案
#include<bits/stdc++.h>
using namespace std;
#define int long long
#define double long double
#define _rep(i,a,b) for(int i=(int)(a);i<=(int)b;++i)
#define IOS ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
#define pb push_back
#define pp pop_back()
#define fi first
#define se second
#define all(x) (x).begin(),(x).end()
#define laile cout<<"laile"<<endl;
typedef pair<int,int> PII;
typedef pair<double,double> PDD;
int n,m,k;
const int N=1e6+10,INF=4e18;
struct aa{int i,j,w;
};
struct cmp{bool operator()(aa a,aa b){return a.w<b.w;}
};
vector<PII>v;
PII get(string &s){int a=0,b=0,now=0;for(auto i:s){if(isdigit(i)){now=now*10+i-'0';}else if(i==' '){a=now;now=0;}}return {a,now};
}
void solve()
{cin>>n;string s;getline(cin,s);while(n--){getline(cin,s);PII t=get(s);v.pb(t);}sort(all(v));multiset<int>now;for(auto i:v){if(!now.size()){now.insert(i.se);}else{int ma=0,maidx;bool bl=false;auto t=now.lower_bound(i.fi);if(t==now.begin()){now.insert(i.se);}else{t--;int tt=i.se;now.erase(t);now.insert(tt);}}}cout<<now.size()<<'\n';
}
signed main()
{IOS;int T=1;
// cin>>T;while(T--)solve();return 0;
}
L2-056 被n整除的n位數
可以發現滿足前i位被i整除的數字其實并不多,那么這題實際上就是直接暴力,這里我用的方法是逐位遞增,用vector<int>v[16]存前i位滿足在區間內部的所有數字,比如a=34567,b=66666,
首先v[1]顯然可以存[3,4,5,6],
然后v[2]利用v[1]的值,遍歷0~9,相當于枚舉了30,31,32,33....40,41,....,68,69這些數字
然后用被 i 整除這個條件可以篩掉大部分數字,然后合法的又存到v[2]里,以此類推
#include<bits/stdc++.h>
using namespace std;
#pragma GCC optimize(2)
#define int long long
#define double long double
#define _rep(i,a,b) for(int i=(int)(a);i<=(int)b;++i)
#define IOS ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
#define pb push_back
#define pp pop_back()
#define fi first
#define se second
#define all(x) (x).begin(),(x).end()
#define laile cout<<"laile"<<endl;
typedef pair<int,int> PII;
typedef pair<double,double> PDD;
int n,m,k;
const int N=1e6+10,INF=4e18;
int qmi(int a,int b){int res=1;while(b){if(b&1)res=res*a;a=a*a;b>>=1;}return res;
}
struct aa{int i,j,w;
};
struct cmp{bool operator()(aa a,aa b){return a.w<b.w;}
};
int get(int x){if(x==0)return 1;int res=0;while(x){x/=10;res++;}return res;
}
bool check(int x){if(get(x)!=n)return false;vector<int>now;while(x){now.pb(x%10);x/=10;}reverse(all(now));int cnt=0,sum=0;for(auto i:now){sum=sum*10+i;cnt++;if(sum%cnt!=0)return false;}return true;
}
vector<int>v[20];
int la[20],lb[20];
int nine(int x){int res=9;_rep(i,1,x-1){res=res*10+9;}return res;
}
void solve()
{int a,b;cin>>n>>a>>b;bool bl=false;if(get(a)<n){int t=1;_rep(i,1,n-1){t*=10;}a=t;}else if(get(a)>n){cout<<"No Solution";return;}if(get(b)>n){int t=9;_rep(i,1,n-1){t=t*10+9;}b=t;}else if(get(b)<n){cout<<"No Solution";return;}vector<int>aa,bb;int c=a;while(c){aa.pb(c%10);c/=10;}reverse(all(aa));c=b;while(c){bb.pb(c%10);c/=10;}reverse(all(bb));for(int i=1;i<=n;i++){la[i]=la[i-1]*10+aa[i-1];lb[i]=lb[i-1]*10+bb[i-1];}_rep(i,0,9){v[1].pb(i);}_rep(i,2,n){_rep(k,0,9){for(auto j:v[i-1]){int t=((j*10)+k);if(t%i==0&&t>=la[i]&&t<=lb[i]){v[i].pb(t);}}}}vector<int>res;for(auto i:v[n]){if(check(i)){res.pb(i);bl=true;}}sort(all(res));if(!bl)cout<<"No Solution";else{res.erase(unique(all(res)),res.end());for(int i=0;i<(int)res.size();i++){cout<<res[i]<<'\n';}}
}
signed main()
{IOS;int T=1;
// cin>>T;while(T--)solve();return 0;
}
L3-040 人生就像一場旅行
類似最短路計數的思想
可以更新旅費(新路線旅費>原路線旅費)更新旅費和心情
否則如果新路線旅費=原路線旅費,更新心情更大的那條
#include<bits/stdc++.h>
using namespace std;
#pragma GCC optimize(2)
#define _rep(i,a,b) for(int i=(int)(a);i<=(int)b;++i)
#define IOS ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
#define pb push_back
#define pp pop_back()
#define fi first
#define se second
#define all(x) (x).begin(),(x).end()
#define laile cout<<"laile"<<endl;
typedef pair<int,int> PII;
typedef pair<double,double> PDD;
int n,m,k;
const int N=1e6+10,INF=4e18;
int qmi(int a,int b){int res=1;while(b){if(b&1)res=res*a;a=a*a;b>>=1;}return res;
}
int sum;
int g[510][510];
int happy[510][510];
int dist[510][510];
void solve()
{cin>>sum>>n>>m>>k;memset(g,0x3f,sizeof(g));_rep(i,1,n){g[i][i]=0;}_rep(i,1,m){int a,b,w,h;cin>>a>>b>>w>>h;g[a][b]=g[b][a]=w;happy[a][b]=happy[b][a]=h;}_rep(k,1,n){_rep(i,1,n){_rep(j,1,n){if(g[i][k]+g[k][j]<g[i][j]){g[i][j]=g[i][k]+g[k][j];happy[i][j]=happy[i][k]+happy[k][j];}else if(g[i][k]+g[k][j]==g[i][j])happy[i][j]=max(happy[i][k]+happy[k][j],happy[i][j]);}}}_rep(i,1,k){int x;cin>>x;vector<int>a,b;int ma=0;_rep(j,1,n){if(x==j)continue;if(g[x][j]<=sum){a.pb(j);if(happy[x][j]>ma){ma=happy[x][j];b.clear();b.pb(j);}else if(happy[x][j]==ma){b.pb(j);}}}if(!a.size()){cout<<"T_T\n";}else {sort(all(a));sort(all(b));for(int i=0;i<(int)a.size();i++){cout<<a[i]<<" \n"[i==(int)a.size()-1];}for(int i=0;i<(int)b.size();i++){cout<<b[i]<<" \n"[i==(int)b.size()-1];}}}
}
signed main()
{IOS;int T=1;
// cin>>T;while(T--)solve();return 0;
}
L3-041 影響力
按題意暴力20分
#include<bits/stdc++.h>
using namespace std;
#pragma GCC optimize(2)
#define int long long
#define _rep(i,a,b) for(int i=(int)(a);i<=(int)b;++i)
#define IOS ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
#define pb push_back
#define pp pop_back()
#define fi first
#define se second
#define all(x) (x).begin(),(x).end()
#define laile cout<<"laile"<<endl;
typedef pair<int,int> PII;
typedef pair<double,double> PDD;
int n,m,k;
const int N=1e6+10,INF=4e18;
vector<vector<int>>v(N);
void solve()
{cin>>n>>m;_rep(i,1,n){v[i].pb(0);_rep(j,1,m){int x;cin>>x;v[i].pb(x);}}_rep(i,1,n){_rep(j,1,m){int res=0;_rep(k,1,n){_rep(l,1,m){res+=v[i][j]*max(abs(k-i),abs(l-j));}}cout<<res<<" \n"[j==m];}}
}
signed main()
{IOS;int T=1;
// cin>>T;while(T--)solve();return 0;
}
L3-042 污染大亨
暴力dfs16分
有一個細節,dfs的時候會遍歷到不同的游戲情況,在回溯完之后為了確定某個小鎮是否被污染,判斷污染的st數組可以直接開int型,每一次被污染就st[u]++,回溯就st[u]--,這樣可以保證st[u]=0時走到這個分支時小鎮從未被污染
#include<bits/stdc++.h>
using namespace std;
#pragma GCC optimize(2)
#define int long long
#define double long double
#define _rep(i,a,b) for(int i=(int)(a);i<=(int)b;++i)
#define IOS ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
#define pb push_back
#define pp pop_back()
#define fi first
#define se second
typedef pair<int,int> PII;
typedef pair<double,double> PDD;
int n,m,k;
const int N=1e6+10,INF=4e18,P=998244353;
vector<vector<int>>v(N);
int c[N];
int st[N];
int sum;
int qmi(int a,int b,int P){int res=1;while(b){if(b&1)res=res*a%P;a=a*a%P;b>>=1;}return res;
}
void infact(int u){sum++;st[u]++;for(auto i:v[u]){infact(i);}return;
}
void finfact(int u){st[u]--;for(auto i:v[u]){finfact(i);}return;
}
int res=0;
void dfs(int u,vector<int>&ve,int now){bool bl=false;_rep(i,1,n){if(st[i])continue;bl=true;sum=0;infact(i);dfs(u+1,ve,now*qmi(c[u],sum,P)%P);finfact(i);}if(!bl)res+=now,res%=P;
}
void solve()
{cin>>n;if(n==1){cout<<n<<'\n';}else {_rep(i,2,n){int x;cin>>x;v[x].pb(i);}_rep(i,1,n)cin>>c[i];vector<int>ve;dfs(1,ve,1);cout<<res;}
}
signed main()
{IOS;int T=1;
// cin>>T;while(T--)solve();return 0;
}