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;
}
相关推荐
byxdaz9 小时前
C++内存序
c++
优雅的潮叭9 小时前
c++ 学习笔记之 malloc
c++·笔记·学习
苦藤新鸡12 小时前
8.最长的无重复字符的子串
c++·力扣
꧁Q༒ོγ꧂12 小时前
C++ 入门完全指南(四)--函数与模块化编程
开发语言·c++
汉克老师12 小时前
GESP2025年12月认证C++八级真题与解析(判断题8-10)
c++·快速排序··lcs·gesp八级·gesp8级
qq_4335545413 小时前
C++ manacher(求解回文串问题)
开发语言·c++·算法
HL_风神14 小时前
设计原则之迪米特
c++·学习·设计模式
HL_风神14 小时前
设计原则之合成复用
c++·学习·设计模式
汉克老师14 小时前
GESP2025年12月认证C++八级真题与解析(单选题10-12)
c++·递归··gesp八级·gesp8级
bkspiderx15 小时前
C++中的map容器:键值对的有序管理与高效检索
开发语言·c++·stl·map