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;
}
相关推荐
AgilityBaby1 小时前
UE5打包项目设置Project Settings(打包widows exe安装包)
c++·3d·ue5·游戏引擎·unreal engine
让我们一起加油好吗3 小时前
【基础算法】高精度(加、减、乘、除)
c++·算法·高精度·洛谷
鑫鑫向栄4 小时前
[蓝桥杯]缩位求和
数据结构·c++·算法·职场和发展·蓝桥杯
stormsha4 小时前
MCP架构全解析:从核心原理到企业级实践
服务器·c++·架构
梁下轻语的秋缘4 小时前
每日c/c++题 备战蓝桥杯(P1204 [USACO1.2] 挤牛奶 Milking Cows)
c语言·c++·蓝桥杯
鑫鑫向栄4 小时前
[蓝桥杯]外卖店优先级
数据结构·c++·算法·职场和发展·蓝桥杯
Zfox_4 小时前
【C++项目】:仿 muduo 库 One-Thread-One-Loop 式并发服务器
linux·服务器·c++·muduo库
wangyuxuan10295 小时前
AtCoder Beginner Contest 399题目翻译
开发语言·c++·算法
?!7146 小时前
Socket网络编程之UDP套件字
linux·网络·c++·网络协议·udp·php
同勉共进6 小时前
虚函数表里有什么?(四)——虚拟继承
c++·虚函数表·虚继承·vtt·construction vtable·vbase_offset·vcall_offset