2025天梯训练1

PTA | L3-1 直捣黄龙 30分

思路:多关键字最短路,同时还要记录最短路径条数。

cpp 复制代码
typedef struct node{
    int from,d,pass,kl;
    bool operator<(const node &x)const{
        if(d!=x.d) return d>x.d;
        if(pass!=x.pass) return pass<x.pass;
        return kl<x.kl;
    }
}node;
int n,m;
string home,en;
unordered_map<string,int> ha;
unordered_map<int,string> antHa;
int enemys[205];
int idx=0;
vector<pair<int,int>> vct[205];
int dis[205];       // 到达i城镇的最短路
int pass[205];      // 到达i城镇经过了多少城镇
int kl[205];      // 到达i城镇杀了多少人
int road[205];    // 当前城镇从哪来
int cnt[205];     // 到达i城镇的最短路条数
bool vis[205];
void dijkstra(int s){
    for(int i=0;i<=idx;i++) dis[i]=LONG_LONG_MAX/2;
    dis[s]=0,pass[s]=0,kl[s]=0,cnt[s]=1;
    priority_queue<node> pq;
    pq.emplace(node{s,0,0,0});
    while(!pq.empty()){
        int from=pq.top().from;
        pq.pop();
        if(vis[from]) continue;
        vis[from]=true;
        for(auto v:vct[from]){
            int to=v.first,w=v.second;
            if(dis[to]>dis[from]+w){    // 距离更短
                dis[to]=dis[from]+w;
                pass[to]=pass[from]+1;
                kl[to]=kl[from]+enemys[to];
                road[to]=from;
                cnt[to]=cnt[from];
                pq.emplace(node{to,dis[to],pass[to],kl[to]});
            }
            else if(dis[to]==dis[from]+w){
                cnt[to]+=cnt[from];
                if(pass[to]<pass[from]+1){
                    pass[to]=pass[from]+1;
                    kl[to]=kl[from]+enemys[to];
                    road[to]=from;
                    pq.emplace(node{to,dis[to],pass[to],kl[to]});
                }
                else if(pass[to]==pass[from]+1){
                    if(kl[to]<kl[from]+enemys[to]){
                        kl[to]=kl[from]+enemys[to];
                        road[to]=from;
                        pq.emplace(node{to,dis[to],pass[to],kl[to]});
                    }
                }
            }
        }
    }
}
void solve(){          // 过了样例就交,一发入魂!~,手术刀一样精准,挺典型的最短路题目,逐次递减的优先级。
    cin>>n>>m;
    cin>>home>>en;
    ha[home]=++idx;
    antHa[idx]=home;
    for(int i=1;i<=n-1;i++){
        string town; cin>>town;
        if(ha[town]==0) ha[town]=++idx,antHa[idx]=town;
        int x; cin>>x;
        enemys[ha[town]]=x;
    }
    for(int i=1;i<=m;i++){
        string t1,t2; cin>>t1>>t2;
        int d; cin>>d;
        vct[ha[t1]].e(ha[t2],d);
        vct[ha[t2]].e(ha[t1],d);
    }
    dijkstra(ha[home]);
    int cur=ha[en];
    stack<string> stk;
    while(cur!=1){
        stk.emplace(antHa[cur]);
        cur=road[cur];
    }
    cout<<home;
    while(!stk.empty()){
        cout<<"->"<<stk.top();
        stk.pop();
    }
    cout<<endl;
    cout<<cnt[ha[en]]<<" "<<dis[ha[en]]<<" "<<kl[ha[en]];
}

PTA | L3-2 拼题A打卡奖励 30分

思路:背包问题,但是要优化:

curSum+=minute[i]; // 不必每次都从m开始转移,这样很白白跑很多不必要的循环..学到了

curSum=min(curSum,m); // 细节!@!

cpp 复制代码
void solve(){
//    cout<<365*24*60*1000;    // 5e8
    int n,m; cin>>n>>m;
    int minute[1003]={0};
    int coin[1003]={0};
    for(int i=1;i<=n;i++) cin>>minute[i];
    for(int i=1;i<=n;i++) cin>>coin[i];
    vector<int> dp(m+5,0);
    int ans=0,curSum=0;
    for(int i=1;i<=n;i++){
        curSum+=minute[i];        // 不必每次都从m开始转移,这样很白白跑很多不必要的循环..学到了
        curSum=min(curSum,m);     // 细节!@!
        for(int j=curSum;j>=minute[i];j--){
            dp[j]=max(dp[j],dp[j-minute[i]]+coin[i]);
            ans=max(ans,dp[j]);
        }
    }
    cout<<ans;
}
相关推荐
大白同学42139 分钟前
【C++】C++11介绍(Ⅱ)
开发语言·c++
油炸自行车1 小时前
【Qt】编写Qt自定义Ui控件步骤
开发语言·c++·qt·ui·自定义ui控件·qt4 自定义ui控件
呱呱巨基3 小时前
C/C++ 内存管理
c++·笔记·学习
半桔3 小时前
【网络编程】TCP 服务器并发编程:多进程、线程池与守护进程实践
linux·服务器·网络·c++·tcp/ip
橘子133 小时前
C++实战:搜索引擎项目(二)
开发语言·c++·搜索引擎
应用市场4 小时前
Qt C++ 图形绘制完全指南:从基础到进阶实战
开发语言·c++·qt
青草地溪水旁4 小时前
设计模式(C++)详解—单例模式(2)
c++·单例模式
bkspiderx4 小时前
C++时区操作全版本指南(含C++03/C++11-17/C++20)
linux·开发语言·c++·c++20·时区
序属秋秋秋5 小时前
《C++进阶之STL》【哈希表】
数据结构·c++·stl·哈希算法·散列表·哈希表·哈希
青草地溪水旁6 小时前
设计模式(C++)详解——建造者模式(1)
c++·设计模式·建造者模式