• ccf 201803-2


    问题描述
      数轴上有一条长度为L(L为偶数)的线段,左端点在原点,右端点在坐标L处。有n个不计体积的小球在线段上,开始时所有的小球都处在偶数坐标上,速度方向向右,速度大小为1单位长度每秒。
      当小球到达线段的端点(左端点或右端点)的时候,会立即向相反的方向移动,速度大小仍然为原来大小。
      当两个小球撞到一起的时候,两个小球会分别向与自己原来移动的方向相反的方向,以原来的速度大小继续移动。
      现在,告诉你线段的长度L,小球数量n,以及n个小球的初始位置,请你计算t秒之后,各个小球的位置。
    提示
      因为所有小球的初始位置都为偶数,而且线段的长度为偶数,可以证明,不会有三个小球同时相撞,小球到达线段端点以及小球之间的碰撞时刻均为整数。
      同时也可以证明两个小球发生碰撞的位置一定是整数(但不一定是偶数)。
     
    输入格式
      输入的第一行包含三个整数n, L, t,用空格分隔,分别表示小球的个数、线段长度和你需要计算t秒之后小球的位置。
      第二行包含n个整数a1, a2, …, an,用空格分隔,表示初始时刻n个小球的位置。
     
    输出格式
      输出一行包含n个整数,用空格分隔,第i个整数代表初始时刻位于ai的小球,在t秒之后的位置。
     
     
    题解:用vector数组存每个坐标被那些顶点占据,如果size为1则不冲突,否则冲突。(不要用二维数组,二维数组太慢辽~)
     
    #include <stdio.h>
    #include <string.h>
    #include <vector>
    #define MAX 105
    #define MAX_LEN 1005
    
    using namespace std;
    
    typedef struct Node{
        int pos;        //位置 
        int dir;        //方向    左0右1 
    }Node;
    
    Node s[MAX];
    vector<int> len[MAX_LEN];    // [坐标位置] :顶点     占据某个坐标位置的顶点集合 
    
    
    int main(){
        int n,l,t;
        int pos;
        while(scanf("%d %d %d",&n,&l,&t)!=EOF){
            for(int i=0;i<=l;i++)    len[i].clear();
            for(int i=1;i<=n;i++){
                scanf("%d",&pos);
                s[i].pos=pos;
                if(pos==l)    s[i].dir=0;        //初始位置在右端点,则方向向左
                else    s[i].dir=1;        //否则,初始方向为右
                len[pos].push_back(i);
            }
            for(int i=1;i<=t;i++){
                for(int j=1;j<=n;j++){
                    if(s[j].dir==1){
                        int p =s[j].pos;
                        for(vector<int>::iterator iter=len[p].begin();iter!=len[p].end();iter++){        //从vector中删除顶点 
                            if(*iter==j){
                                len[p].erase(iter);
                                break;
                            }
                        }
                        s[j].pos++;
                        p++;
                        len[p].push_back(j);        //被顶点j占据
                        if(s[j].pos==l ) s[j].dir=0;                //如果改变后位置在右端点,则方向变左     
                    }
                    else if(s[j].dir==0){
                        int p =s[j].pos;
                        for(vector<int>::iterator iter=len[p].begin();iter!=len[p].end();iter++){        //删除顶点 
                            if(*iter==j){
                                len[p].erase(iter);
                                break;
                            }
                        }
                        s[j].pos--;
                        p--;
                        len[p].push_back(j);
                        if(s[j].pos==0 )    s[j].dir=1;        //如果改变后位置在左端点,方向变右 
                    }
                }
                    for(int k=0;k<=l;k++){
                    if(len[k].size()==1)    continue;        //如果只有一个顶点占据该坐标,则不冲突 
                    for(int i=0;i<len[k].size();i++){        
                        int v=len[k][i];
                        s[v].dir=!s[v].dir;        //如果相撞了,改变顶点的方向 
                    }
                }
            
            }
            for(int i=1;i<=n;i++){
                if(i!=n)    printf("%d ",s[i].pos);
                else    printf("%d
    ",s[i].pos);
            }    
        }
        return 0;
    }
  • 相关阅读:
    来自1068
    耻辱的时间戳(笑哭)
    依然排序
    呵呵
    好吧,第二篇
    来自机房的第一篇博客
    Shader-水流效果
    unity中虚拟摇杆的实现
    (转载)Unity3d中的属性(Attributes)整理
    C#冒泡排序法及优化
  • 原文地址:https://www.cnblogs.com/shiliuxinya/p/12219008.html
Copyright © 2020-2023  润新知