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

    欢迎访问喔

    为了自己,和那些爱你的人
  • 相关阅读:
    70.BOM
    69.捕获错误try catch
    68.键盘事件
    523. Continuous Subarray Sum
    901. Online Stock Span
    547. Friend Circles
    162. Find Peak Element
    1008. Construct Binary Search Tree from Preorder Traversal
    889. Construct Binary Tree from Preorder and Postorder Traversal
    106. Construct Binary Tree from Inorder and Postorder Traversal
  • 原文地址:https://www.cnblogs.com/zhmlzhml/p/15128515.html
Copyright © 2011-2022 走看看