poj 1003坠落的蚂蚁

来源:互联网 发布:linux上svn创建项目 编辑:程序博客网 时间:2024/04/27 17:45

1003:坠落的蚂蚁

  • 查看
  • 提交
  • 统计
  • 提问
总时间限制: 
1000ms 
内存限制: 
65536kB
描述
一根长度为1米的木棒上有若干只蚂蚁在爬动。它们的速度为每秒一厘米或静止不动,方向只有两种,向左或者向右。如果两只蚂蚁碰头,则它们立即交换速度并继续爬动。三只蚂蚁碰头,则两边的蚂蚁交换速度,中间的蚂蚁仍然静止。如果它们爬到了木棒的边缘(0或100厘米处)则会从木棒上坠落下去。在某一时刻蚂蚁的位置各不相同且均在整数厘米处(即1,2,3,…99厘米),有且只有一只蚂蚁A速度为0,其他蚂蚁均在向左或向右爬动。给出该时刻木棒上的所有蚂蚁位置和初始速度,找出蚂蚁A从此时刻到坠落所需要的时间。
输入
第一行包含一个整数表示蚂蚁的个数N(2<=N<=99),之后共有N行,每一行描述一只蚂蚁的初始状态。每个初始状态由两个整数组成,中间用空格隔开,第一个数字表示初始位置厘米数P(1<=P<=99),第二个数字表示初始方向,-1表示向左,1表示向右,0表示静止。
输出
蚂蚁A从开始到坠落的时间。若不会坠落,输出“Cannot fall!”
样例输入
410 190 095 -198 -1
样例输出

98

这道题,千万不要想得太细了,否则你就完全的被带进去了,你要统筹规下的去思考这道题:

换句话的意思就是说:要综合考虑那个A两边的情况(而且具体些是左边的只考虑向右走的蚂蚁,右边的只考虑向左走的蚂蚁,再细一点的过程就不要多想了,因为即使在一边有两个相反的方向,那么结果只能够是其中一个替代了另一个,举个例子,在中间A(处在50的位置)的左边有两只蚂蚁,一只在10号位置,方向向右,还有一只蚂蚁在40的位置,方向向左,考虑做百年的情况,这两只在25的地方相遇,交换方向,也就是那个原来是10号地方的蚂蚁变换方向,变成左边,直接从0走出去了,而那只原本在40的蚂蚁会变成向右的方向,朝着A走来,这种情况就相当于在10号位置的向右一直走,一直到与A相遇的情况是一样的,也就是说忽略那只向左走的40号位置的蚂蚁一样,右边类似,只需要找向左边走的右边蚂蚁)

解题思路是:

找到A左边的向右边走的蚂蚁个数,并且放进新的数组ans,把A放进数组ans,同理也找到A右边的向左走的蚂蚁个数,并且放心那个数组ans;最后判断左边的蚂蚁数和右边的蚂蚁数,如果左边的大于右边,那么就意味着左边会多出蚂蚁,使得A继续往右边,也就是说A从100的位置掉下,那么应该从哪里开始算起时间的?好好想下,给你一个例子,总共有1,2,3,A,4,5这几个蚂蚁,A左边的是1,2,3,右边的是4和5,当然都是符合前边说过的方向要求的,左边的往右走,右边的往左走,最后的时间应该是拿100-ans[1].position,简单点理解就是2,3和4,5关于A对称,那么就取最靠近这种对称的一个,如果是1,2,3,4,5,6,A,7,8那么也是100-ans[4].position,前边的1,2,3都是赶不上4的,用公式表示就是100-ans[center-right-1].position,同理,如果left<right,那么就是ans[center+left+1].position,从0厘米处出去,如果是left===right,那么就是不会出去的,他们一直都在上边的。

下边来看代码:

#include<iostream>
#include<cstring>
using namespace std;
#include<cstdio>
#include<algorithm>
#include<queue>
#include<stack>
#define ref(i,x,y) for(int i=x;i<=y;i++)
#define def(i,x,y) for(int i=x;i>=y;i--)
#define ini(a,i) memset(a,i,sizeof (a));
#define MAX_N 105
#define LL long long
#define INF 10000000
using namespace std;
int n,m;
struct s
{
    int pos,sd;
    bool operator<(struct s &a)
    {
        return pos<a.pos;
    }
}data[MAX_N];
void solve()
{
    int hasTouchCenter=false;
    struct s ans[MAX_N];
    int k=0,left=0,right=0,center;
    ref(i,1,n)
    {
        if(data[i].sd==1&& !hasTouchCenter)//左边的往右走的蚂蚁
        {
            ans[++k]=data[i];
            left++;
        }


        if(!data[i].sd)//中间的蚂蚁
        {
            hasTouchCenter=true;
            ans[++k]=data[i];
            center=k;
        }


        if(data[i].sd==-1&& hasTouchCenter)//右边的往左走的蚂蚁
        {
            ans[++k]=data[i];
            right++;
        }
    }
    if(left==right)     cout<<"Cannot fall!"<<endl;
    else if(left<right) cout<<ans[center+left+1].pos<<endl;
    else cout<<100-ans[center-right-1].pos<<endl;
}
int main()
{
//    freopen("F:\\cb代码文件\\input\\input.txt","r",stdin);
    while(~scanf("%d",&n))
    {
        ref(i,1,n)cin>>data[i].pos>>data[i].sd;
        sort(data+1,data+1+n);
        solve();
    }
    return 0;
}


0 0
原创粉丝点击