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;
}
相关推荐
pipip.15 分钟前
UDP————套接字socket
linux·网络·c++·网络协议·udp
孞㐑¥5 小时前
Linux之Socket 编程 UDP
linux·服务器·c++·经验分享·笔记·网络协议·udp
水木兰亭8 小时前
数据结构之——树及树的存储
数据结构·c++·学习·算法
CoderCodingNo9 小时前
【GESP】C++四级考试大纲知识点梳理, (7) 排序算法基本概念
开发语言·c++·排序算法
秋风&萧瑟10 小时前
【C++】C++中的友元函数和友元类
c++
梁诚斌11 小时前
使用OpenSSL接口读取pem编码格式文件中的证书
开发语言·c++
2301_8035545215 小时前
c++中的绑定器
开发语言·c++·算法
海棠蚀omo15 小时前
C++笔记-位图和布隆过滤器
开发语言·c++·笔记
消失的旧时光-194316 小时前
c++ 的标准库 --- std::
c++·jni
GiraKoo16 小时前
【GiraKoo】C++11的新特性
c++·后端