[OpenJudge 3064]坠落的蚂蚁
试题描述
一根长度为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!”
输入示例
4 10 1 90 0 95 -1 98 -1
输出示例
98
数据规模及约定
见“输入”
题解
如果不考虑蚂蚁的编号,观察当两只蚂蚁撞上后调换方向其实和互相穿过没什么区别,所以能掉出去的蚂蚁一定会在 100 步内掉出(我们可以假设蚂蚁可以互相穿过,那么最晚掉下去的蚂蚁要么是开始时最左边向右走的或是最右边向左走的,而它们掉下去的步数显然不会超过 100)。
那么就暴力模拟 100 步咯。(有许多细节,不如拆成 200 步走,即每两个时刻的正中间再加一个时刻。)
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <stack>
#include <vector>
#include <queue>
#include <cstring>
#include <string>
#include <map>
#include <set>
using namespace std;
const int BufferSize = 1 << 16;
char buffer[BufferSize], *Head, *Tail;
inline char Getchar() {
if(Head == Tail) {
int l = fread(buffer, 1, BufferSize, stdin);
Tail = (Head = buffer) + l;
}
return *Head++;
}
int read() {
int x = 0, f = 1; char c = getchar();
while(!isdigit(c)){ if(c == '-') f = -1; c = getchar(); }
while(isdigit(c)){ x = x * 10 + c - '0'; c = getchar(); }
return x * f;
}
#define maxn 110
int n;
struct Ant {
int x, v, id;
bool has, pau;
Ant() {}
Ant(int _, int __, int ___): x(_), v(__), id(___) {}
void Move() {
if(!pau) x += v;
pau = 0;
return ;
}
bool operator < (const Ant& t) const { return x != t.x ? x < t.x : v < t.v; }
} as[maxn];
bool cmp(Ant a, Ant b) { return a.id < b.id; }
int main() {
// freopen("data.in", "r", stdin);
while(scanf("%d", &n) == 1) {
int tar;
for(int i = 1; i <= n; i++) {
int a = read(), b = read();
as[i] = Ant(a << 1, b, i); as[i].has = 1;
if(!as[i].v) tar = i;
}
bool ok = 0;
for(int i = 1; i <= 200; i++) {
for(int j = 1; j <= n; j++) as[j].Move();
sort(as + 1, as + n + 1);
for(int j = 1; j <= n; j++) if(as[j].has) {
if(as[j].x == 0 || as[j].x == 200) {
if(as[j].id == tar){ printf("%d\n", i >> 1); ok = 1; break; }
as[j].has = 0;
}
else if(as[j].x == as[j+1].x && as[j+1].x == as[j+2].x) swap(as[j].v, as[j+2].v), sort(as + j, as + j + 3), j++;
else if(as[j].x == as[j+1].x) swap(as[j].v, as[j+1].v), sort(as + j, as + j + 2);
}
if(ok) break;
// sort(as + 1, as + n + 1, cmp);
// for(int j = 1; j <= n; j++) if(as[j].x < 10) printf("%d %d %d\n", as[j].id, as[j].x, as[j].v); putchar('\n');
}
if(!ok) puts("Cannot fall!");
}
return 0;
}