UVa 10881 Piotr's Ants (直接模拟)

来源:互联网 发布:如何挑选油烟机知乎 编辑:程序博客网 时间:2024/06/10 15:03

-
来源:《算法竞赛入门经典训练指南》第1章例题5、UVa 10881
题目描述:

L长的木棍上有n只蚂蚁,每只蚂蚁要么向左爬要么向右爬,秒速一个单位长度.两只蚂蚁若相撞则掉头,给出每只蚂蚁初始状态和朝向,按输入顺序输出T秒后各只


题目分析:

迫不得已开了一个新的分类,这个题除了模拟实在归不到别的地方去了.


非常明显的模拟,由于以前做过判断所有蚂蚁什么时候掉下去的题,所以对两只蚂蚁碰撞可视为穿过这一点没有思维障碍.这一题在此基础上只加了一重关卡,即要按照输入的顺序来输出,这样就要求知道具体到第一只蚂蚁,它最后到底在哪里.


嘛这个就是本题的难点了,一下看不出来可以挑几只蚂蚁手动模拟一下观察规律,可以看到在碰撞即回头的约束条件下每只蚂蚁保持着在数轴(木棍)上的序,这样就好办了,记录一开始从左到右的顺序,把它和输入顺序关联起来,在由此从Final态中按照相同的顺序还原出输入顺序,具体参照代码实现,注意理清楚这两个序是怎么转换的,把映射搞明白了也就做出来了.

//  Created by wander on 16/06/20.//  Copyright © 2016年 W4anD0eR96. All rights reserved.//  From: UVa-10881//  Sort: 模拟#include "bits/stdc++.h"using namespace std;const int MAXN = 10050;const char DIRECTION[][10] = { "L", "Turning", "R" };struct Ant { int id, pos, dir; }Raw[MAXN], Final[MAXN]; // dir表示蚂蚁当前朝向:-1:左;0:转身;1:右bool operator < (const Ant& a, const Ant& b) { return a.pos < b.pos; }int kase, L, T, n, id[MAXN];                            // id数组记录输入数据中第i只蚂蚁最后的排序id[i]int main() {#ifdef DEBUG  freopen("in", "r", stdin);  freopen("out", "w", stdout);#endif  scanf("%d", &kase);  for (int nCase = 1; nCase <= kase; nCase += 1) {    // input and pre-process    scanf("%d%d%d", &L, &T, &n);    for (int i = 0; i < n; i += 1) {      int pos, dir; char ch;      scanf("%d %c", &pos, &ch);      dir = (ch != 'L' ? 1 : -1);      Raw[i] = (Ant){ i, pos, dir };      Final[i] = (Ant){ 0, pos + T * dir, dir };    }    // 计算Final态蚂蚁的序号id[i]    sort(Raw, Raw + n);    for (int i = 0; i < n; i += 1) id[Raw[i].id] = i;    // 计算Final态蚂蚁的方向和位置    sort(Final, Final + n);    for (int i = 0; i < n - 1; i += 1)      if (Final[i].pos == Final[i + 1].pos)        Final[i].dir = Final[i + 1].dir = 0;    // output    printf("Case #%d:\n", nCase);    for (int i = 0; i < n; i += 1) {      int t = id[i];      if (Final[t].pos < 0 || Final[t]. pos > L) puts("Fell off");      else printf("%d %s\n", Final[t].pos, DIRECTION[Final[t].dir + 1]);    }    putchar('\n');  }  return 0;}
0 0
原创粉丝点击