zoukankan      html  css  js  c++  java
  • 【Codeforces Round #431 (Div. 1) B】

    【链接】h在这里写链接


    【题意】


    场上有 n 个点,它们分别向上与向右在不同时刻开始运动,相遇则改变移动方向,求最终这些点到达的坐标。

    【题解】


    先把每个点的坐标都往它本该移动的方向相反的方向退ti个单位。
    这样,就相当于每个点都是同时开始运动的了。
    想象一下,两个点同时碰撞的条件.
    假设碰撞的点坐标为(x,y);
    则初始的时候他们的坐标分别为(x-t,y)以及(x,y-t);
    会发现,这两个点的x+y的值是一样的。
    (这里的x,y是每个点都退ti个单位后的点x,y)
    所以,能够发生碰撞的条件,就是x+y的值是一样的。
    也即,他们同在一条直线y = -x + z上。
    则我们把所有在同一条直线y = -x + z上的点都归为一组。
    一组一组的处理。
    (会发现,这组里面的点只会和组内部的点发生碰撞);
    这些规律画图就很容易得到的。
    然后,我们把这些点从左上到右下一个一个处理。
    就能发现规律的。
    会发现,左边,下边出来的点,都依照点的顺序投射到上,上右,右上,右下。
    画图!别光看题解。


    【错的次数】


    0

    【反思】


    把每个点都往后移动。
    抓住碰撞的条件是什么。
    把点按照能碰撞的分为一组。
    不难模拟出规律的。

    【代码】

    #include <bits/stdc++.h>
    using namespace std;
    
    const int N = 1e5;
    
    int n, w, h, g[N + 10], p[N + 10], t[N + 10];
    pair <int, int> ans[N + 10];
    map <int, vector<int> > dic;
    vector <int> vx, vy;
    
    void in() {
        cin >> n >> w >> h;
    
        for (int i = 1; i <= n; i++) {
            cin >> g[i] >> p[i] >> t[i];
            dic[p[i] - t[i]].push_back(i);
        }
    }
    
    bool cmp(int x, int y) {
        return p[x] < p[y];
    }
    
    void get_ans() {
        for (pair <int, vector<int> > temp : dic) {
            int len = temp.second.size();
    
            for (int i = 0; i <= len - 1; i++)
                if (g[temp.second[i]] == 1) {
                    vx.push_back(temp.second[i]);
                }
                else {
                    vy.push_back(temp.second[i]);
                }
    
                sort(vx.begin(), vx.end(), cmp);
                sort(vy.begin(), vy.end(), cmp);
    
                int k = (int)vy.size() - 1 - (int)vx.size() + 1;
                k = max(k, 0);
                for (int i = (int)vy.size() - 1; i >= k; i--) {
                    int temp = (int)vy.size() - i - 1;
                    ans[vy[i]].first = p[vx[temp]], ans[vy[i]].second = h;
                }
    
                for (int i = k - 1; i >= 0; i--) {
                    int temp = k - i;
                    ans[vy[i]].first = w, ans[vy[i]].second = p[vy[(int)vy.size() - temp]];
                }
    
                k = (int)vx.size() - 1 - (int)vy.size() + 1;
                k = max(k, 0);
                for (int i = (int)vx.size() - 1; i >= k; i--) {
                    int temp = (int)vx.size() - i - 1;
                    ans[vx[i]].first = w, ans[vx[i]].second = p[vy[temp]];
                }
    
                for (int i = k - 1; i >= 0; i--) {
                    int temp = k - i;
                    ans[vx[i]].first = p[vx[(int)vx.size() - temp]], ans[vx[i]].second = h;
                }
                vx.clear(), vy.clear();
        }
    }
    
    void out() {
        for (int i = 1; i <= n; i++)
            cout << ans[i].first << ' ' << ans[i].second << endl;
    }
    
    int main() {
        ios::sync_with_stdio(0), cin.tie(0);
        in();
        get_ans();
        out();
        return 0;
    }


  • 相关阅读:
    VS2013 调试窗口一闪而过的解决方法
    什么是文件?
    局部变量和全局变量的区别
    一个简单java程序的要素
    运行一个简单的Java程序
    Javascript 构造函数原型继承机制
    函数式编程之一等公民的函数
    弹性布局flex-兼容问题
    TypeScript中的枚举类型
    依赖注入
  • 原文地址:https://www.cnblogs.com/AWCXV/p/7626035.html
Copyright © 2011-2022 走看看