zoukankan      html  css  js  c++  java
  • 1072 Gas Station (30 分) 二三四测试点没过看过来!!

    题目详情
    先来嚷嚷一波:这个题给的样例有问题!!那个3.3其实应该是3.2!
    可是。。。咋就这么多测试点没过
    给大伙秀一波惨案
    在这里插入图片描述
    零零散散的正确错误的
    俺debug了好久啊呜呜呜,会有人感谢我的!!!
    喔对了,其实如果零零散散正确错误的应该是代码细节有问题,你就得再读读题看看是不是有哪个变量写错了呀or是不是哪个细节处理错了。如果有大小比较的一定要再看看~有没有赋值就赋一半的?之类的。

    如果是前几个对了后面的全错,请考虑数据范围please!!

    这个题数据范围是1000+10不过你读入数据的时候也要注意, 不能getchar搞定啊!它可能不是一位数啊!(测试点四就是这样)用string搞起!

    咱讲究图文并茂:
    咱讲究图文并茂

    然后好好审题,这个题的第一标尺可不是总路径最近,而是距离最近的那个点最远
    就是说每个加油站跑完最短路找距离最近的那个house,然后所有加油站比比找这个点最远的。

    最近的最远....第二三个测试点错的小朋友看过来!

    看看这段代码:
    就是如果d[j]比那个D大,那就求all,能更新本次最小值就更新
    如果不大,,,那本次最小值为INF(这是一个很大的数)
    在这里插入图片描述
    这里有什么问题呢?
    最小值不合法就弄个最大的数,看起来真的没有问题。
    (这个地方卡了本菜鸡很久,并且一度以为是测评机坏掉了QAQ)

    但是啊,你底下是不是要求这个最小值的最大值啊?
    在这里插入图片描述
    你这直接赋值个最大,怎么判断minloc不合法啊,,,

    所以改进的话就是把刚刚不合法赋值INF的地方赋值一个最小值,然后这里再判断一遍

    然后二三样例就过了,,,,

    这个题除了这里卡我了一下,再提几个注意点:

    • 首先你得注意跑最短路的时候是可以以别的加油站点为中介的(所以是M+N个点)
    • 跑多个dij别忘记每次赋值(for个1024下真的时间不长,,不会TLE放心)
      你都跑多个dij了还怕TLE????
    • 这个题给的样例有问题!!那个3.3其实应该是3.2
      这个题不需要四舍五入的(如果四舍五入就是+0.05)没必要

    wa了二三测试点的代码(铭记历史才能勇往直前(狗头)

    #include<vector>
    #include<iostream>
    #include <algorithm>
    #include <cmath>
    #include<map>
    #include <queue>
    #include <stack>
    #include<string.h>
    using namespace std;
    const int INF=100000;
    int G[1024][1024];
    //直接把两个存在一起 1~1000 1001~1010
    int M,N,K,D;
    int d[1024];
    double minloc;
    int vis[1024];
    double gas_all=INF;
    double gas_min=-1;
    void init(){
        for (int i = 0; i <1024 ; ++i) {
            for (int j = 0; j < 1024; ++j) {
                G[i][j]=INF;
                G[j][i]=INF;
    
            }
    
        }
    }
    void init_dij(){
        for (int i = 0; i <= M+N; ++i) {
            d[i]=INF;
            vis[i]=0;
    
        }
    
    }
    int get_one(){
        int u=0;
        string p;
        cin>>p;//输入不能用char,可能会出现G11,199这样的数字
        if(p[0]=='G'){
            for(int j=1;j<p.length();j++){
                u=u*10+p[j]-'0';
            }
            u+=M;
        }else{
            for(int j=0;j<p.length();j++){
                u=u*10+p[j]-'0';
            }
        }
        return u;
    }
    //d数组就是到每个点的距离了,其实这里都不需要存路径,,,用d直接说事就行了,反正d已经是最短路
    void dij(int v){
        init_dij();//d需要更新
        d[v]=0;
        for (int i = 1; i <= M+N; ++i) {
            int u=-1,MIN=INF;
            for (int j = 1; j <= M+N ; ++j) {
                if(vis[j]==0 && d[j]<MIN){
                    u=j;
                    MIN=d[j];
                }
            }
            if(u==-1) return ;
            vis[u]=1;
            for (int j = 1; j <= M+N ; ++j) {
                if(vis[j]==0 && G[j][u]!=INF ){
                    if(d[j]>d[u]+G[j][u]){
                        d[j]=d[u]+G[j][u];
    
                    }
                }
    
            }
    
        }
    
    
    
    }
    
    int main(){
        cin>>M>>N>>K>>D;//M houses; N gas ;K roads; D is the range  下标1 M+N
        init();
        for (int i = 0; i < K; ++i) {
            int a1=get_one();
            int a2=get_one();
            int l;
            cin>>l;
            G[a1][a2]=l;
            G[a2][a1]=l;
            //cout<<a2<<a1<<endl;
    
        }
        //对所有gas进行dij
        double all;
        //all 每次的和 minloc 每次的最小值
        //gas_all 全局的和 gas_min 全局的最小值
    
        int choosegas=-1;
        for (int i = M+1; i <=M+N ; ++i) {
            minloc=INF;
            all=0;
            dij(i);
            for (int j = 1; j <= M; ++j) {
                if(d[j]<=D) {
                    //每次的和 每次的最小值
                    all += d[j];
                    if (d[j] < minloc) {
                        minloc = d[j];
                    }
                }
                else{
                    all=0;
                    minloc=INF;
                    break;
                }
            }
            //cout<<"min&all:"<<minloc<<" "<<all<<endl;
            if(minloc>gas_min){//最小值得最大值
                gas_min=minloc;
                gas_all=all;
                choosegas=i;
                //  cout<<"gas:"<<choosegas<<endl;
            }
            else if(minloc==gas_min && all<gas_all){//all 尽量小
                gas_all=all;
                choosegas=i;
                //cout<<"gas:"<<choosegas<<endl;
            }
    
        }
        if(minloc!=INF){
            cout<<"G"<<choosegas-M<<endl;
            double out1=gas_min;
    
            double out2=gas_all/M;
            //cout<<"ouut"<<out2<<endl;
            printf("%.1f %.1f
    ",out1,out2);
            //cout<<choosegas<<" "<<gas_all<<" "<<gas_min;
    
        }
        else{
            cout<<"No Solution"<<endl;
        }
        return 0;
    
    
    }
    

    AC代码:(我冲了

    #include<vector>
    #include<iostream>
    #include <algorithm>
    #include <cmath>
    #include<map>
    #include <queue>
    #include <stack>
    #include<string.h>
    using namespace std;
    const int INF=1000000;
    int G[1024][1024];
    //直接把两个存在一起 1~1000 1001~1010
    int M,N,K,D;
    int d[1024];
    double minloc;
    int vis[1024];
    double gas_all=INF;
    double gas_min=-1;
    void init(){
        for (int i = 0; i <1024 ; ++i) {
            for (int j = 0; j < 1024; ++j) {
                G[i][j]=INF;
                G[j][i]=INF;
    
            }
    
        }
    }
    void init_dij(){
        for (int i = 0; i <= M+N; ++i) {
            d[i]=INF;
            vis[i]=0;
    
        }
    
    }
    int get_one(){
        int u=0;
        string p;
        cin>>p;//输入不能用char,可能会出现G11,199这样的数字
        if(p[0]=='G'){
            for(int j=1;j<p.length();j++){
                u=u*10+p[j]-'0';
            }
            u+=M;
        }else{
            for(int j=0;j<p.length();j++){
                u=u*10+p[j]-'0';
            }
        }
        return u;
    }
    //d数组就是到每个点的距离了,其实这里都不需要存路径,,,用d直接说事就行了,反正d已经是最短路
    void dij(int v){
        init_dij();//d需要更新
        d[v]=0;
        for (int i = 1; i <= M+N; ++i) {
            int u=-1,MIN=INF;
            for (int j = 1; j <= M+N ; ++j) {
                if(vis[j]==0 && d[j]<MIN){
                    u=j;
                    MIN=d[j];
                }
            }
            if(u==-1) return ;
            vis[u]=1;
            for (int j = 1; j <= M+N ; ++j) {
                if(vis[j]==0 && G[j][u]!=INF ){
                    if(d[j]>d[u]+G[j][u]){
                        d[j]=d[u]+G[j][u];
    
                    }
                }
    
            }
    
        }
    
    
    
    }
    
    int main(){
        cin>>M>>N>>K>>D;//M houses; N gas ;K roads; D is the range  下标1 M+N
        init();
        for (int i = 0; i < K; ++i) {
            int a1=get_one();
            int a2=get_one();
            int l;
            cin>>l;
            G[a1][a2]=l;
            G[a2][a1]=l;
            //cout<<a2<<a1<<endl;
    
        }
        //对所有gas进行dij
        double all;
        //all 每次的和 minloc 每次的最小值
        //gas_all 全局的和 gas_min 全局的最小值
    
        int choosegas=-1;
        for (int i = M+1; i <=M+N ; ++i) {
            minloc=INF;
            all=0;
            dij(i);
    
            for (int j = 1; j <= M; ++j) {
                if(d[j]<=D) {
                    //每次的和 每次的最小值
                    all += d[j];
                    if (d[j] < minloc) {
                        minloc = d[j];
                    }
                }
                else{
                    all=0;
                    minloc=-1;
                    break;
                }
    
            }
            if(minloc==-1){
                continue;
            }
            //cout<<"min&all:"<<minloc<<" "<<all<<endl;
            if(minloc>gas_min){//最小值得最大值
                gas_min=minloc;
                gas_all=all;
                choosegas=i;
              //  cout<<"gas:"<<choosegas<<endl;
            }
            else if(minloc==gas_min && all<gas_all){//all 尽量小
                gas_all=all;
                choosegas=i;
                //cout<<"gas:"<<choosegas<<endl;
            }
    
        }
        if(minloc!=-1){
            cout<<"G"<<choosegas-M<<endl;
            double out1=gas_min;
    
            double out2=gas_all/M;
            //cout<<"ouut"<<out2<<endl;
            printf("%.1f %.1f
    ",out1,out2);
            //cout<<choosegas<<" "<<gas_all<<" "<<gas_min;
    
        }
        else{
            cout<<"No Solution"<<endl;
        }
        return 0;
    
    
    }
    

    折腾这么久真不容易哇

    喔,俺最近博客都写在csdn上咯

    地址在这:

    https://blog.csdn.net/weixin_49599247/article/details/119607570

    欢迎访问喔

    为了自己,和那些爱你的人
  • 相关阅读:
    C#获取网上图片的宽高代码
    发现两个有趣的CSS3效果
    .NET WinForm画树叶小程序
    生产环境使用 pt-table-checksum 检查MySQL数据一致性【转】
    awk入门【转】
    MySQL数据库之auto_increment【转】
    crontab的使用方法
    linux添加swap分区【转】
    nginx反向代理转发后页面上的js css文件无法加载【原创】
    Serv-U日志文件保存设置【转】
  • 原文地址:https://www.cnblogs.com/zhmlzhml/p/15128515.html
Copyright © 2011-2022 走看看