您的位置:首页 > 大数据 > 物联网

UVA - 10881 - Piotr's Ants

2015-04-17 21:08 363 查看
传送门:

http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=25979

题意:

蚂蚁在单杠上爬,互相碰撞就转向。输入杠长,持续时间,还有蚂蚁数量。最后得出所有蚂蚁的位置。

① 蚂蚁因碰撞而掉头时,看上去就是两个点“对穿而过”。

② 如,蚂蚁点A(1,R),在碰撞的两秒后,存在点A'(3,R),只是(3,R)是另外一只蚂蚁。A与A'方向一样。

③ 其实无论怎么碰撞,原本在杠上的顺序abcdefg,碰撞后还是abcdefg的顺序,而且原本的顺序。

④ 只需要按照原来的顺序和方向,计算出N秒后各个点的位置(计算时,方向保持不变),再套用原来的顺序abcdefg,从左到右套用在N秒后的顺序上即可。

⑤ 根据输入的顺序,对应输出结果。不是简单的从左到右。所以要保存好原来的输入顺序,用数组做好映射(Mapping)。

注意:

① 要根据输入的顺序,输出对应蚂蚁的位置结果。

思路:

① 保存原有状态(位置和方向)

② 根据位置,从左到右排序出结果;并使用数组实现从“原输入顺序的id”到“排序后的id”的映射。

③ 模拟N秒后的状态,并进行位置的排序。

④ 根据原有从左到右的id,分配到N秒后的顺序上。结合“映射”按顺序输出结果。

总结:

① 智商低,就是更要多看看别人代码,学学思想;静下心来思考。


定义类或结构体的时候,用其来声明数组时,有时会出错;因为没有定义一个默认构造函数(无参数)。


适当把输出文本放在数组里,根据结果对应输出数组内容,快速、而且方便管理。

④ 在进行“==”操作对比时,居然用数字比'R',或者字母比'1';不要以为‘==’两边顺其自然就是同类型数据,要理解各位置各变量的内容!低级错误不能有。

STL版本<使用list和stack>:Memery 0 KB/Time 129 ms

#include <iostream>
#include <algorithm>
#include <stdio.h>

using namespace std;

// Local Test
// #define LOCAL_TEST

// used to define Array
const int MAX_SIZE = 10000 + 2;

// define class CAnt
// "before" array store original "InputOrder" and position/direction
struct CAnt
{
// InputOrder number
int id;
// Position on pole
int pos;
// Direction, "-1" means "left", "0" means "turning", "1" means "right"
int dir;
// constructed function
CAnt(int a, int b, int c):id(a), pos(b), dir(c){}
// If define array, class needs a constructed function
// for setting default value
CAnt(){id=0; pos=0; dir=0;}
// operator for "sort" function
bool operator < (const CAnt &b){return pos<b.pos;}
} before[MAX_SIZE], after[MAX_SIZE];

// A Mapping for turning "InputOrder number" to the sorted array's index
int mpInOrderToSorted[MAX_SIZE];
// faster Mapping from "index" to "direction string"
char outStr[][10] = {"L", "Turning", "R"};

int main()
{
#ifdef LOCAL_TEST
freopen("..\\in.txt", "r", stdin);
freopen("..\\out.txt", "w+", stdout);
#endif
// ------- Solution by using Sync(false)
std::ios::sync_with_stdio(false);
std::cin.tie(0);

// Store the number of Cases
int nCase;
cin >>nCase;
// Every case processing
for ( int index=0; index<nCase; index++ )
{
// Get "maxLen", the length of pole
// Get "timePass", the time passed
// Get "nAnts", the number of Ants
int maxLen, timePass, nAnts;
cin >>maxLen >>timePass >>nAnts;
// Get input data
for ( int i=0; i<nAnts; i++ )
{
// the current "i" means the inputOrder
int id = i;
// Get position(integer) and direction(char)
int pos;
char c;
cin >>pos >>c;
// char to integer.
// Take care of 'R' (letter with single quotes mark)
int dir = (c=='R'?1:-1);
// store data to "before" array
before[i] = CAnt(id, pos, dir);
// use easy formula "pos+dir*timepass"
// to calculate the positions after the time
// By the way, directions remain unchanged
after[i] = CAnt(0, pos+dir*timePass, dir);
} // end for

// 'Cause "inputOrder" is out of order From left to right on the pole
// We need to sort the array data.
// From the sorted array, we can get a order sequence while it means
// the current order and the future order(they're the same)
sort(before, before+nAnts);
// After sorted, we miss the inputOrder,
// use another array to store a Mapping
// From "InputOrder"[0~n] to "poleOrder"(current or future)
for ( int i=0; i<nAnts; i++ )
mpInOrderToSorted[before[i].id] = i;

// sort the array after moving
// Get the final Ants' position
sort(after, after+nAnts);
// while neighbour Ants together means "Turning" direction
// Set to "0"
for ( int i=0; i<nAnts-1; i++ )
if ( after[i].pos == after[i+1].pos )
after[i].dir = after[i+1].dir = 0;

cout <<"Case #" <<index+1 <<":" <<endl;
for ( int i=0; i<nAnts; i++ )
{
int a = mpInOrderToSorted[i];
if ( after[a].pos<0	|| after[a].pos>maxLen )
cout <<"Fell off" <<endl;
else
cout <<after[a].pos <<" " <<outStr[after[a].dir+1] <<endl;
} // end for
cout <<endl;
} // end for

return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: