CSP CCF: 201803-2 碰撞的小球 (C++)

题目来源

碰撞的小球

注意点

  1. 输入数据可能是无序的。
  2. 输出时需要按照输入时小球的顺序来输出他们的位置。

代码

#include <iostream>
#include <algorithm>
#include <map>
#include <vector>

using namespace std;

struct Node{
    int loc;
    int dir;  // 1 : 向右; -1: 向左
};

vector<Node> nodes; // vector的话方便排序

bool cmp(Node a, Node b) {
    return a.loc < b.loc;
};

int main() {
    int N,L,T;
    cin>>N>>L>>T;

    for (int i = 0; i < N; ++i) {
        int cur;
        cin>>cur;
        nodes.push_back(Node{cur, 1});
    }

    // 
    map<int, int> mymap1, mymap2;
    for (int i = 0; i < N; ++i) {  // 记录原始数据的位置与下标的映射关系
        mymap1[nodes[i].loc] = i;
    }
    sort(nodes.begin(), nodes.end(), cmp);   // 原始数据可能是无序的, 需要排序
    for (int i = 0; i < N; ++i) {  // 记录排序后数据的位置与下标的映射关系
        mymap2[nodes[i].loc] = i;
    }
    int indexs[N];  // new 2 original
    int index = 0;
    for (pair<int, int> p: mymap2) {  // 记录排序后数据与原始数据的下标的映射关系
        indexs[index++] = mymap1[p.first];
    }

    //
    for (int i = 0; i < T; ++i) {  // i 时刻
        Node nxtnodes[1002];

        // 全部到下一步的位置
        for (int j = 0; j < N; ++j) {
            if (nodes[j].loc == 0 ) {  // <0, x> -> <1, 1>
                nxtnodes[j].loc = 1;
                nxtnodes[j].dir = 1;
                //cout<<"1: "<<endl;
            }
            else if (nodes[j].loc == L) {  // <L, x> -> <L - 1, -1>
                nxtnodes[j].loc = L - 1;
                nxtnodes[j].dir = -1;
                //cout<<"2: "<<endl;
            }
            else {
                nxtnodes[j].loc = nodes[j].loc + nodes[j].dir;
                nxtnodes[j].dir = nodes[j].dir;
                //cout<<"3: "<<nxtnodes[j].loc<<" "<<nxtnodes[j].dir<<endl;
            }
        }

        // 发生碰撞(两个球的位置一样),则更改方向
        for (int j = 0; j < N; ++j) {
            if (j < N - 1 && nxtnodes[j].loc ==  nxtnodes[j + 1].loc) {  // 相撞
                nodes[j].loc = nxtnodes[j].loc;
                nodes[j + 1].loc = nxtnodes[j + 1].loc;
                nodes[j].dir = -1;
                nodes[j + 1].dir = 1;
                ++j;
            }
            else {
                nodes[j].loc = nxtnodes[j].loc;
                nodes[j].dir = nxtnodes[j].dir;
            }
        }
    }

    // 一定要记得输出的时候得按原来的顺序
    int ans[N];
    for (int i = 0; i < N; ++i) {
        ans[indexs[i]] = nodes[i].loc;
    }
    for(int i = 0; i < N; ++i) {
        cout<<ans[i]<<" ";
    }
    cout<<endl;


    return 0;
}


  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值