• 编程练习赛41:题目1 : 比赛日程安排


    题目1 : 比赛日程安排

    时间限制:10000ms
    单点时限:1000ms
    内存限制:256MB

    描述

    H国编程联赛中有N只队伍,编号1~N。 他们计划在2018年一共进行M场一(队)对一(队)的比赛。  

    为了让参赛队员能得到充分的休息,联赛组委会决定:每支队伍连续两场比赛之间至少间隔一天。也就是如果A队1月1日参加了一场比赛,那么下一场比赛最早安排在1月3日。  

    给定M场比赛的时间和参赛的两支队伍,请你判断这个日程安排是否可行。

    输入

    第一行包含一个整数T,代表测试数据组数。(1 ≤ T ≤ 10)

    对于每组数据,第一行包含两个整数N和M。(1 ≤ N ≤ 50, 1 ≤ M ≤ 1000)  

    以下M行每行描述一场比赛,包含比赛日期(格式MM-DD),以及2支参赛队伍的编号。

    输出

    对于每组数据输出YES或者NO,代表日程安排是否可行。

    样例输入
    2  
    3 3  
    01-01 1 2  
    01-03 1 3  
    01-05 2 3  
    4 4  
    02-01 4 3  
    01-30 4 1  
    01-31 1 2  
    01-30 2 3
    样例输出
    YES  
    NO

    思路:

    输入数据进行保存,然后统计每只队伍的比赛日期,只要有一只队伍的比赛时间不满足要求,此次结果就是false,打印NO。

    这次难点有对输入数据的处理存储想了很久,处理的时候对每组数据进行处理判断,得到结果后再对下一次的输入数据进行处理,处理的思路是统计每一只队伍的比赛时间,然后转化为整数,这里需要注意可能相差很多月份,所以要使用/100对月份进行判断,这里的依据是日期的格式是固定的,就可以对输入的xx-yy进行处理,更好的方法是使用scanf(%s-%d %d),直接将输入转化为整数,节省很多工作量。

    转化为整数后,月份一样的直接前后相减,月份相差很大的肯定不会重复,所以肯定是对的,月份相差为1的需要重点对待,使用的方法是i所在的月份日期 + i -1月天数 - 100。

    总结收获:输入的处理,stoi转化为整数,直接将字符串输入就可以转化为整数,string tmp,int i =stoi(tmp);

    scanf的运用。

    因为每一组数据中的队伍只要有一个安排不对,那么整个数组的安排就是错的,需要返回false,然后马上break,结束当前循环,因为不break的话,后面会将result变量修改为true;

    还有需要注意的地方是N只队伍,使用的时候是第i只队伍,所以数组的大小是N+ 1,访问的时候i要从1开始访问。

    自己写的版本,通过了是90/100

    #include<vector>
    #include<algorithm>
    #include<string>
    #include<iostream>
    
    using namespace std;
    struct node {
        string day;
        int left;
        int right;
        
        node(string s, int x, int y) :day(s), left(x), right(y) {}
    };
    struct nm {
        int N;
        int M;
        bool result;
        nm(int x,int y,bool res = true):N(x),M(y),result(res) {}
    };
    vector<int> month{0,31,28,31,30,31,30,31,31,30,31,30,31};
    
    bool isOk(vector<string> &alltime) {
        if (alltime.size() == 0) {
            return false;
        }    
        vector<int> timeint;
        for (int i = 0; i < alltime.size();++i) {
            string tmp;
            for (int j = 0; j < 5; ++j) {//xx-yy
                
                if (j == 2) {
                    continue;
    
                }
                tmp.push_back(alltime[i][j]);
                        
            }
            int tmpint = stoi(tmp);
            timeint.push_back(tmpint);
        }
        sort(timeint.begin(), timeint.end());    
        //for (int i : timeint) {
        //    cout << i << endl;
        //}
        for (int i = 0; i < timeint.size(); ++i) {
            if (i != 0) {
                int i1, i2;
                i1 = timeint[i - 1] / 100;
                i2 = timeint[i] / 100;
                if (i1 == i2) {
                    //cout << timeint[i] - timeint[i - 1] << endl;
                    if (abs(timeint[i] - timeint[i - 1]) < 2) {
                        return false;
                    }
                    //cout << timeint[i] - timeint[i - 1] << endl;
                }
                else if ((i2 - i1) > 1) {
                    continue;
                }
                else  if(i2 - i1 == 1){
                    int a = timeint[i] + month[i1] - 100;
                    if (abs(a - timeint[i - 1]) < 2) {
                        return false;
                    }
                    //cout << a - timeint[i - 1] << endl;
                }
                
            }
        }
        return true;
    }
    void judge(vector<node> &input, nm &NMRes) {
        int N = NMRes.N;
        int M = NMRes.M;
        //bool res = NMRes.result;
        vector<vector<string>> totalTime(N + 1,vector<string> ());//每只队伍所有的比赛时间
        for (int i = 0; i < M; ++i) {        
            totalTime[input[i].left].push_back(input[i].day);
            totalTime[input[i].right].push_back(input[i].day);    
        }
        //判断是否每只队伍都只相隔一天的比赛日期
        for (int i = 1; i <= N; ++i) {
            if (isOk(totalTime[i])) {
                NMRes.result = true;
            }
            else {
                NMRes.result = false;
                break;
            }
        }    
    }
    
    int main() {
        int T;//T组测试数据
        int N;//N只队伍
        int M;//M场比赛,string
        cin >> T;
        nm nmTmp(0, 0);
        vector<nm> nmVec(T, nmTmp);//存输入的队伍和比赛总次数以及最后的判断结果
        //int i = 0;
        vector<node> inputOfOne;//每组比赛的数据
        vector<vector<node>> inputTotal;//所有比赛的数据
        for (int i = 0; i < T; ++i) {
            cin >> nmVec[i].N >> nmVec[i].M;
            for (int j = 0; j < nmVec[i].M; ++j) {//输入一组数据
                node tmpNode("",0,0);
                cin >> tmpNode.day >> tmpNode.left >> tmpNode.right;
                inputOfOne.push_back(tmpNode);
            }
            inputTotal.push_back(inputOfOne);
            vector<node>().swap(inputOfOne);
        }
        //对每组数据进行judge判断
        for (int i = 0; i < T; ++i) {
            judge(inputTotal[i], nmVec[i]);
        }
        //输出结果
        for (int k = 0; k < T; ++k) {
            if (nmVec[k].result) {
                cout << "YES" << endl;
            }
            else {
                cout << "NO" << endl;
            }
        
        }
        system("pause");
    }
    自己写的版本

    优化版本:ac

    #include <iostream>
    #include <stdio.h>
    #include <utility>
    #include <algorithm>
    using namespace std;
    
    int months[12] = {31,28,31,30,31,30,31,31,30,31,30,31};
    int main() {
        int T;
        cin >> T;
        while (T--) {
            int N, M;
            cin >> N >> M;
            vector<vector<pair<int,int>> > v(N + 1);
            for (int i = 0; i < M; ++i) {
                int month, day, c1,c2;
                scanf("%d-%d %d %d", &month, &day, &c1, &c2);
                v[c1].push_back(make_pair(month, day));
                v[c2].push_back(make_pair(month, day));
            }
            bool flag = true;
            for (int i = 1; i < N + 1; ++i) {
                sort(v[i].begin(), v[i].end());
                for (int j = 1; j < v[i].size(); ++j) {
                    if (v[i][j].first == v[i][j - 1].first) {
                        if (v[i][j].second - v[i][j - 1].second < 2) {
                            flag = false;
                            break;
                        }
                    }
                    else if (v[i][j].first - v[i][j - 1].first > 1) {
                        continue;
                    }
                    else {
                        if (v[i][j].second + months[v[i][j - 1].first - 1] - v[i][j - 1].second < 2) {
                            flag = false;
                            break;
                        }
                    }
                }
                if (flag == false) {
                    cout << "NO" << endl;
                    break;
                }
            }
            if (flag == true) {
                cout << "YES" << endl;
            }
        }
    }
    View Code
  • 相关阅读:
    教你不编程快速解析 JSON 数据
    教你在 Linux 下时光穿梭
    在Linux系统中使用Vim读写远程文件
    【高并发】如何实现亿级流量下的分布式限流?这些理论你必须掌握!!
    【高并发】高并发环境下构建缓存服务需要注意哪些问题?我和阿里P9聊了很久!
    【高并发】关于线程池,蚂蚁金服面试官问了我这些内容!!
    【高并发】关于乐观锁和悲观锁,蚂蚁金服面试官问了我这几个问题!!
    机器学习 | 简介推荐场景中的协同过滤算法,以及SVD的使用
    Python | Python初学者的自我修养,找到自己的方向
    LeetCode 86 | 链表基础,一次遍历处理链表中所有符合条件的元素
  • 原文地址:https://www.cnblogs.com/dingxiaoqiang/p/8098638.html
Copyright © 2020-2023  润新知