PAT天梯赛刷题记录(更新中~只记录有思考价值的题)

L1-058 6翻了

if+while循环处理相同字符个数

L1-059 敲笨钟

rfind和erase的妙用

L1-064 估值一亿的AI核心代码

正则表达式

#include<bits/stdc++.h>
using namespace std;
int main(){
    int n;cin>>n;
    string s;getline(cin,s);
    while(n--){
        getline(cin,s);
        cout<<s<<endl;
        s=regex_replace(s,regex(R"(\s+)")," ");
        s=regex_replace(s,regex(R"( \!)"),"!");
        s=regex_replace(s,regex(R"( \?)"),"?");
        s=regex_replace(s,regex(R"( \,)"),",");
        s=regex_replace(s,regex(R"( \.)"),".");
        s=regex_replace(s,regex(R"( \')"),"'");
        if(s[0]==' ')s.erase(0,1);
        if(s.back()==' ')s.pop_back();
        for(auto &i:s){
            if(i!='I')i=tolower(i);
        }
        
        s=regex_replace(s,regex(R"(\bcan you\b)"),"_I can");
        s=regex_replace(s,regex(R"(\bcould you\b)"),"_I could");
        s=regex_replace(s,regex(R"(\bI\b)"),"you");
        s=regex_replace(s,regex(R"(\bme\b)"),"you");
        s=regex_replace(s,regex(R"(\?)"),"!");
        s=regex_replace(s,regex(R"(\b_I\b)"),"I");
        cout<<"AI: "<<s<<endl;
    }
}

L3-001 凑零钱

01背包(先用大物品再用小物品)+输出路径

#include<bits/stdc++.h>
using namespace std;
#define int long long
#define all(x) x.begin(),x.end()
#define no cout<<"No"<<endl
#define yes cout<<"Yes"<<endl
#define endl '\n'
// #define x first
// #define y second
typedef pair<int,int> PII;
const int N=200010;
const int mod=998244353;
const int INF=0x3f3f3f3f3f3f3f3f;
int dp[N];
int vis[N][105];
void solve(){
    int n,m;cin>>n>>m;
    vector<int>v(n);
    for(int i=0;i<n;i++)cin>>v[i];
    sort(all(v),greater<int>());
    dp[0]=1;
    for(int i=0;i<n;i++){
        for(int j=m;j>=v[i];j--){
            if(dp[j-v[i]]){
                dp[j]=1;
                vis[i][j]=1;
            }
        }
    }
    vector<int>ans;n--;
    if(dp[m])while(m){
        if(vis[n][m]){
            ans.push_back(v[n]);
            m-=v[n];
        }
        n--;
    }
    if(ans.size()){
        for(int i=0;i<ans.size();i++){
            if(i)cout<<' '<<ans[i];
            else cout<<ans[i];
        }
    }else cout<<"No Solution\n";
}
signed main(){
    ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
    int _=1;
    while(_--)solve();
    return 0;
}

L3-002 特殊堆栈

树状数组+二分(求第k小)

#include<bits/stdc++.h>
using namespace std;
#define lowbit(x) (x&(-x))
const int N=1e5+10;
int tr[N];
void add(int t,int val){
    for(int i=t;i<N;i+=lowbit(i)){
        tr[i]+=val;
    }
}
int query(int t){
    int res=0;
    for(int i=t;i;i-=lowbit(i)){
        res+=tr[i];
    }
    return res;
}
int main(){
    int n;cin>>n;
    stack<int>st;
    for(int i=0;i<n;i++){
        string s;cin>>s;
        if(s=="Pop"){
            if(st.empty()){
                cout<<"Invalid\n";
                continue;
            }
            int x=st.top();st.pop();
            add(x,-1);
            cout<<x<<endl;
        }else if(s=="PeekMedian"){
            if(st.empty()){
                cout<<"Invalid\n";
                continue;
            }
            int x=((int)st.size()+1)/2;
            int l=0,r=N;
            while(l+1!=r){
                int mid=l+r>>1;
                if(query(mid)>=x)r=mid;
                else l=mid;
            }
            cout<<r<<endl;
        }else{
            int x;cin>>x;
            st.push(x);
            add(x,1);
        }
    }
}

L3-003 社交集群

稍微有点思维的并查集

#include<bits/stdc++.h>
using namespace std;
const int N=1005;
int root[N];
int sz[N];
int find(int a){
    if(a==root[a])return a;
    return root[a]=find(root[a]);
}
void merge(int a,int b){
    int ra=find(a),rb=find(b);
    if(ra>rb)swap(ra,rb);
    sz[ra]+=sz[rb];
    root[rb]=ra;
}
int main(){
    int n;cin>>n;
    for(int i=0;i<N;i++)root[i]=i;
    for(int i=0;i<n;i++){
        string s;cin>>s;
        string t;
        for(auto i:s){if(i==':')break;
            t+=i;             
        }
        int k=stoi(t);
        int a;cin>>a;
        sz[find(a)]++;
        for(int j=0;j<k-1;j++){
            int b;cin>>b;
            merge(a,b);
        }
    }
    vector<int>ans;
    for(int i=1;i<N;i++){
        if(sz[find(i)])
        if(i==find(i))
        ans.push_back(sz[find(i)]);
    }
    sort(ans.begin(),ans.end(),greater<int>());
    cout<<ans.size()<<endl;
    for(int i=0;i<ans.size();i++){
        if(i)cout<<' ';
        cout<<ans[i];
    }
}

L3-004 肿瘤诊断

三维bfs

#include<bits/stdc++.h>
using namespace std;
int dir[6][3]={0,0,1,0,0,-1,0,1,0,0,-1,0,-1,0,0,1,0,0};
int g[1300][130][70];
int book[1300][130][70];
int main(){
    int m,n,l,t;cin>>m>>n>>l>>t;
    for(int i=0;i<l;i++){
        for(int j=0;j<m;j++){
             for(int k=0;k<n;k++){
                 cin>>g[j][k][i];
             }
        }
    }
    int ans=0;
    for(int i=0;i<l;i++){
        for(int j=0;j<m;j++){
             for(int k=0;k<n;k++){
                 if(!book[j][k][i]&&g[j][k][i]==1){
                     int cnt=1;
                     book[j][k][i]=1;
                     queue<array<int,3>>q;
                     q.push({j,k,i});
                     while(q.size()){
                         auto [a,b,c]=q.front();
                         q.pop();
                         for(int p=0;p<6;p++){
                             int tx=a+dir[p][0],ty=b+dir[p][1],tz=c+dir[p][2];
                             if(tx<0||ty<0||tz<0||tx>=m||ty>=n||tz>=l||book[tx][ty][tz]||g[tx][ty][tz]==0)continue;
                             book[tx][ty][tz]=1;
                             cnt++;
                             q.push({tx,ty,tz});
                         }
                     }
                     if(cnt>=t)ans+=cnt;
                 }
             }
        }
    }
    cout<<ans<<endl;
}

L3-005 垃圾箱分布

刚开始理解错题意了,就是个裸的Dijkstra

O(m*n+klogn)

L3-007 天梯地图

经典Dijkstra+dfs

#include<bits/stdc++.h>
using namespace std;
const int N=550;
const int INF=0x3f3f3f3f;
vector<array<int,3>>v[N];
int d1[N];
int d2[N];
int n,m;
int st,ed;
void Dijkstra1(){
    for(int i=0;i<n;i++)d1[i]=INF;
    vector<int>book(n);
    d1[st]=0;
    for(int i=0;i<n;i++){
        int mn=INF,t;
        for(int j=0;j<n;j++){
            if(!book[j]&&mn>=d1[j]){
                mn=d1[j];
                t=j;
            }
        }
        if(book[t])continue;
        book[t]=1;
        for(auto [j,w1,w2]:v[t]){
            if(book[j])continue;
            d1[j]=min(d1[j],w1+mn);
        }
    }
}
void Dijkstra2(){
    for(int i=0;i<n;i++)d2[i]=INF;
    vector<int>book(n);
    d2[st]=0;
    for(int i=0;i<n;i++){
        int mn=INF,t;
        for(int j=0;j<n;j++){
            if(!book[j]&&mn>=d2[j]){
                mn=d2[j];
                t=j;
            }
        }
        if(book[t])continue;
        book[t]=1;
        for(auto [j,w1,w2]:v[t]){
            if(book[j])continue;
            d2[j]=min(d2[j],w2+mn);
        }
    }
}
int cnt=INF;
vector<int>ans1;
vector<int>ans2;
vector<int>tmp;
void dfs1(int t,int fa,int ndist,int ncnt){
    if(ndist>d1[t])return;
    if(t==ed){
        if(ncnt<cnt){
            ans1=tmp;
            cnt=ncnt;
        }
        return;
    }
    for(auto [j,a,b]:v[t]){
        if(j==fa)continue;
        tmp.push_back(j);
        dfs1(j,t,ndist+a,ncnt+1);
        tmp.pop_back();
    }
}
int dist=INF;
void dfs2(int t,int fa,int nTm,int ndist){
    if(nTm>d2[t])return;
    if(t==ed){
        if(ndist<dist){
            ans2=tmp;
            dist=ndist;
        }
        return;
    }
    for(auto [j,a,b]:v[t]){
        if(j==fa)continue;
        tmp.push_back(j);
        dfs2(j,t,nTm+b,ndist+a);//这里的参数一定要用对啊,一直忘
        tmp.pop_back();
    }
}
int main(){
    cin>>n>>m;
    for(int i=0;i<m;i++){
        int a,b,c,d,e;cin>>a>>b>>c>>d>>e;
        v[a].push_back({b,d,e});
        if(!c)v[b].push_back({a,d,e});
    }
    cin>>st>>ed;
    Dijkstra1();
    Dijkstra2();
    tmp.push_back(st);
    dfs1(st,st,0,0);
    dfs2(st,st,0,0);
    if(ans1==ans2){
        printf("Time = %d; Distance = %d: %d",d2[ed],d1[ed],st);
        for(int i=1;i<ans1.size();i++){
            printf(" => %d",ans1[i]);
        }
    }else{
        printf("Time = %d: %d",d2[ed],st);
        for(int i=1;i<ans2.size();i++){
            printf(" => %d",ans2[i]);
        }cout<<'\n';
        printf("Distance = %d: %d",d1[ed],st);
        for(int i=1;i<ans1.size();i++){
            printf(" => %d",ans1[i]);
        }
    }
}

L3-011 直捣黄龙

经典Dijkstra+dfs

#include<bits/stdc++.h>
using namespace std;
#define PII pair<int,int>
unordered_map<string,int>mp;
unordered_map<int,string>mp2;
const int N=220;
const int INF=0x3f3f3f3f;
int val[N];
vector<PII>v[N];
int idx=0;
int d[N];
string st,ed;
int n,k;
void Dijkstra() {
	for(int i=0; i<n; i++)d[i]=INF;
	d[mp[st]]=0;
	vector<int>book(n);
	for(int i=0; i<n; i++) {
		int mn=INF,t;
		for(int j=0; j<n; j++) {
			if(!book[j]&&mn>=d[j]) {
				mn=d[j];
				t=j;
			}
		}
		if(book[t])continue;
		book[t]=1;
		for(auto [j,w]:v[t]) {
			if(book[j])continue;
			if(d[j]>mn+w) {
				d[j]=mn+w;
			}
		}
	}
}
vector<int>ans;
vector<int>tmp;
int ans2,cnt,sum,dist;
void dfs(int t,int fa,int nsum,int ncnt,int ndist) {
	if(ndist>d[t])return;
	if(t==mp[ed]) {
		ans2++;
		if(ncnt>cnt) {
			ans=tmp;
			cnt=ncnt;
			sum=nsum;
		} else if(ncnt==cnt&&nsum>sum) {
			ans=tmp;
			cnt=ncnt;
			sum=nsum;
		}
		return;
	}
	for(auto [j,w]:v[t]) {
		if(j==fa)continue;
		tmp.push_back(j);
		dfs(j,t,nsum+val[j],ncnt+1,ndist+w);
		tmp.pop_back();
	}
}
int main() {
	cin>>n>>k;
	cin>>st>>ed;
	mp[st]=idx;mp2[idx++]=st;
	mp[ed]=idx;mp2[idx++]=ed;
	for(int i=0; i<n-1; i++) {
		string a;int b;
		cin>>a>>b;
		if(!mp.count(a)) {
			mp[a]=idx;
			mp2[idx++]=a;
		}
		val[mp[a]]=b;
	}
	for(int i=0; i<k; i++) {
		string a,b;int c;
		cin>>a>>b>>c;
		v[mp[a]].push_back({mp[b],c});
		v[mp[b]].push_back({mp[a],c});
	}
	Dijkstra();
	tmp.push_back(mp[st]);
	dfs(mp[st],mp[st],0,0,0);
	for(int i=0; i<ans.size(); i++) {
		if(i)cout<<"->";
		cout<<mp2[ans[i]];
	}cout<<endl;
	cout<<ans2<<' '<<d[mp[ed]]<<' '<<sum;
}

 L3-022 地铁一日游

题意太抽象

Floyd写错了

#include<bits/stdc++.h>
using namespace std;
const int N=220;
const int INF=0x3f3f3f3f;
int d[N][N];
set<int>st[N];
int ru[N];
string line;
vector<int>v;
vector<int>book(N);
void dfs(int t){
	for(auto j:st[t]){
		if(book[j])continue;
		book[j]=1;
		v.push_back(j);
		dfs(j);
	}
}
int main(){
    int n,m,k;cin>>n>>m>>k;getline(cin,line);
    for(int i=1;i<=n;i++)for(int j=1;j<=n;j++)d[i][j]=INF,d[i][i]=0;
    for(int i=0;i<m;i++){
        getline(cin,line);
        stringstream ssin(line);
        string s;vector<int>tmp;
        while(ssin>>s)tmp.push_back(stoi(s));
        for(int i=0;i<tmp.size();i+=2){
        	if(i==0)ru[tmp[i]]=1;
            if(i==tmp.size()-1){ru[tmp[i]]=1;break;}
            d[tmp[i]][tmp[i+2]]=min(d[tmp[i]][tmp[i+2]],tmp[i+1]);
            d[tmp[i+2]][tmp[i]]=min(d[tmp[i+2]][tmp[i]],tmp[i+1]);
        }
    }
    
    for(int k = 1; k <= n; k++)//Floyd
		for(int i = 1; i <= n; i++)
			for(int j = 1; j <= n; j++)
				if(i!=j)d[i][j] = min(d[i][j],d[i][k]+d[k][j]);
    
    for(int i=1;i<=n;i++){
        map<int,int>mp;
        st[i].insert(i);
        for(int j=1;j<=n;j++){
            if(d[i][j]==INF)continue;
            mp[2+d[i][j]/k]=max(mp[2+d[i][j]/k],d[i][j]);
        }
        for(int j=1;j<=n;j++){
            if(d[i][j]==INF)continue;
            if(d[i][j]==mp[2+d[i][j]/k]||ru[j]==1){
                st[i].insert(j);
            }
        }
    }
    
    int q;cin>>q;
    while(q--){
        int x;cin>>x;
        v.clear();
        book.assign(N,0);
        book[x]=1;
        dfs(x);
        for(auto i:v){
            st[x].insert(i);
        }
        int fir=1;
        for(auto i:st[x]){
            if(fir){cout<<i;fir=0;}
            else cout<<' '<<i;
        }cout<<endl;
    }
}

L3-025 那就别担心了

dfs逆向思维(一直误以为是拓扑排序)

L3-031 千手观音

离散化+优先队列+拓扑排序

L3-032 关于深度优先搜索和逆序对的题应该不会很难吧这件事

树状数组求树上逆序对

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值