1004. Intersection (思维 / 判断 / 假模拟) (2020年百度之星*程序设计大赛-初赛三)

传送门

1004. Intersection (思维 / 判断 / 假模拟) (2020年百度之星*程序设计大赛-初赛三)_第1张图片
1004. Intersection (思维 / 判断 / 假模拟) (2020年百度之星*程序设计大赛-初赛三)_第2张图片
1004. Intersection (思维 / 判断 / 假模拟) (2020年百度之星*程序设计大赛-初赛三)_第3张图片
思路:

  • 官方题解:
    在这里插入图片描述

  • 这就是个假的模拟题,看着唬人,其实不难。

  • 我们只需要考虑左右车道的最后一个车就好,证明:

    • 我们不考虑停留的情况,停留的时候还是要耗时所以并没有意义。
    • 右车道的车:只有走自己的道才是时间最短,且前面的车在移动的同时后面的车也在跟着一起移动,所有前面的车不会对后面的车造成影响。
    • 左车道的车:可选择在刚过x线后直接往右走(即变道到右车道),这样它到y线右侧所需时间会少1. 但是你不能阻碍右车道的车。同样前面的车怎样走不会影响后面的车。
    • 而对于左侧车提前变道会不会时间更短,其实不然,若变道不影响右侧车,那么还是以右侧车花的时间为准(因为它更大)。若左侧车变道会让右侧车等1s,那么右侧车后面都会整体多1s。这样减少1s又增加1s并没有什么意义。
  • 所以总体来说只需要考虑两个车道最后一个车就好,因为答案要求的就是最后的时间。而关于最后车的判断详细见代码。

代码实现:

#include
#define endl '\n'
#define null NULL
#define ll long long
#define int long long
#define pii pair
#define lowbit(x) (x &(-x))
#define ls(x) x<<1
#define rs(x) (x<<1+1)
#define me(ar) memset(ar, 0, sizeof ar)
#define mem(ar,num) memset(ar, num, sizeof ar)
#define rp(i, n) for(int i = 0, i < n; i ++)
#define rep(i, a, n) for(int i = a; i <= n; i ++)
#define pre(i, n, a) for(int i = n; i >= a; i --)
#define IOS ios::sync_with_stdio(0); cin.tie(0);cout.tie(0);
const int way[4][2] = {{1, 0}, {-1, 0}, {0, 1}, {0, -1}};
using namespace std;
const int  inf = 0x7fffffff;
const double PI = acos(-1.0);
const double eps = 1e-6;
const ll   mod = 1e9 + 7;
const int  N = 1e5 + 5;

int t, n;

signed main()
{
    IOS;

    cin >> t;
    while(t --){
        cin >> n;
        int lmax = 0, rmax = 0;
        while(n --){
            int x, y; cin >> x >> y;
            if(x == 1) rmax = max(rmax, y);
            else lmax = max(lmax, y);
        }
        //若左右两道最后的车并排或者左侧车在后都已左侧车时间为答案,且左侧车可以在x上变道
        if(lmax == rmax || lmax > rmax) cout << lmax + 2 << endl;
        else{
            //如果右侧车在左侧车右下方,以左侧车为答案,且它不能变道
            if(rmax == lmax + 1 && lmax) cout << lmax + 3 << endl;
            else cout << rmax + 1 << endl; //否则右侧车最后直接就是它为答案
        }
    }

    return 0;
}

你可能感兴趣的:(比赛&训练)