2014百度之星初赛第一轮解题报告:information
2014-05-28 23:19
225 查看
[align=left]Information[/align] [align=left]时间限制: 1s 内存限制: 65536K[/align] [align=left][/align] [align=left]问题描述[/align] [align=left]军情紧急,我们需要立刻开发出一个程序去处理前线侦察兵发回的情报,并做出相应的分析。现在由你负责其中的一个子模块,你需要根据情报计算出敌方坦克的位置。[/align] [align=left]当敌方坦克静止时,侦察兵会尽力估算出它们之间的位置,而每当敌方坦克移动时,侦察兵都会记录下坦克新的位置并向你报告。每个坦克的位置可以由一个二维整数坐标来描述。[/align] [align=left]前线发回的情报有四种格式:[/align] [align=left]1 A B X Y[/align] 表示A坦克移动到了与B坦克的相对位置是 的地方,即 。 [align=left]2 A X Y[/align] [align=left]表示A坦克移动到了绝对位置是 的地方,即 , 。[/align] [align=left]3 A B X Y[/align] [align=left]表示发现了A坦克与B坦克的相对位置是 ,即 。[/align] [align=left]4 A X Y[/align] [align=left]表示发现了A坦克的绝对位置是 ,即 , 。[/align] [align=left]我们需要你对于如下两种询问及时做出回应:[/align] [align=left]5 A B[/align] [align=left]表示询问A坦克与B坦克的相对位置是多少,即分别求出 以及 。[/align] [align=left]6 A[/align] [align=left]表示询问A坦克的绝对位置是多少,即求出 。[/align] [align=left]其中A和B代表的是任意的一个坦克的编号,(X,Y)表示了坦克的二维坐标。你可以假设初始时刻我们对于敌方任何坦克的位置都一无所知,在此之后坦克的每一次移动都被侦察兵侦察到了。请注意两个坦克的坐标有可能相同。[/align] [align=left][/align] [align=left]输入[/align] 输入的第一行是一个整数T(T< 1000),表示共有T组数据。 [align=left]对于每组数据,第一行有一个整数N,表示这组数据有N次查询。接下来的每行表示一次查询,每次查询第一个数字代表是哪种询问,询问的格式详见上文。[/align] [align=left]数据范围:[/align] [align=left],X和Y都是整数且[/align] [align=left]测试数据中98%的数据N不超过50。[/align] [align=left][/align] [align=left]输出[/align] [align=left]对于每组数据,首先需要输出单独一行”Case#?:”,其中问号处应填入当前的数据组数,组数从1开始计算。[/align] [align=left]对于每一个类型(1)或者(2)的询问,请把它们加入到你的记录中。[/align] [align=left]对于每一个类型(3)或者(4)的询问,如果与之前记录的内容有矛盾,请输出”REJECT”并将这个情报忽略掉,如没有矛盾,请把它们加入到你的记录中。[/align] [align=left]对于每一个类型(5)或者(6)的询问,如果根据之前的记录能推出结论,请输出两个整数X和Y,两个整数之间有一个空格;如果不能推出结论,请输出”UNKNOWN”。输出的所有信息都不包括引号。[/align] [align=left][/align] [align=left]样例输入[/align] [align=left]2[/align] [align=left]7[/align] [align=left]1 1 2 3 4[/align] [align=left]2 3 4 5[/align] [align=left]3 4 5 2 1[/align] [align=left]4 6 2 2[/align] [align=left]3 2 4 6 2[/align] [align=left]5 4 1[/align] [align=left]6 3[/align] [align=left]6[/align] [align=left]6 3[/align] [align=left]4 3 2 2[/align] [align=left]6 3[/align] [align=left]2 4 2 3[/align] [align=left]5 3 4[/align] [align=left]3 3 4 1 2[/align] [align=left][/align] [align=left]样例输出[/align] [align=left]Case #1:[/align] [align=left]-9 -6[/align] [align=left]4 5[/align] [align=left]Case #2:[/align] [align=left]UNKNOWN[/align] [align=left]2 2[/align] [align=left]0 -1[/align] [align=left]REJECT[/align] [align=left]解题报告 –Information[/align] [align=left][/align] [align=left]这题的算法并不复杂,主要就是一个并查集的使用,不过写的时候要注意很多细节。每个Tank的状态可以分3种情况:[/align] [align=left]1. 未初始化,不在任何集合里;[/align] [align=left]2. 在一个互相间已知相对位置的集合里;[/align] [align=left]3. 已知绝对位置。[/align] [align=left][/align] [align=left]具体的处理规则如下:[/align] [align=left]1. 1A B X Y[/align] [align=left]1) 如果A原来在一个集合里,把它从这个集合移除;[/align] [align=left]2) 根据B的情况:[/align] [align=left]a) 如果B已知绝对位置,设置A的绝对位置;[/align] [align=left]b) 如果B不在任何集合里,则创建一个集合,把A、B都加入,并设置相对位置;[/align] [align=left]c) 如果B已经在一个集合里,则把A加入这个集合,并设置相对位置;[/align] [align=left]2. 2 A X Y[/align] [align=left]1) 如果A原来在一个集合里,把它从这个集合移除;[/align] [align=left]2) 设置A的绝对位置;[/align] [align=left]3. 3 A B XY[/align] [align=left]1) 如果A和B其中一个不在任何集合里,则等于把其移到另一个的相对位置上,和类型1的处理流程一样;[/align] [align=left]2) 如果A和B都有绝对位置或者在同一个集合里,判断他们的相对位置是否和这次发现的一致,如果不一致,输出REJECT,忽略本次操作;[/align] [align=left]3) 如果A和B其中一个有绝对位置,则可以把另外一个所在集合里的所有Tank都设置绝对位置;[/align] [align=left]4) 如果A和B在不同的集合里,则把其中一个集合合并到另一个集合,并更新所有Tank的相对位置;[/align] [align=left]4. 4 A X Y[/align] [align=left]1) 如果A已经有绝对位置,判断他的绝对位置是否和这次发现的一致,如果不一致,输出REJECT,忽略本次操作;[/align] [align=left]2) 如果A不在任何集合内,设置A的绝对位置即可;[/align] [align=left]3) 如果A在一个集合内,设置这个集合里的所有Tank的绝对位置;[/align] [align=left]5. 5 A B[/align] [align=left]1) 如果A和B都有绝对位置或者在同一个集合里,输出他们的相对位置;[/align] [align=left]2) 否则输出UNKNOWN;[/align] [align=left]6. 6 A[/align] [align=left]1) 如果A有绝对位置,输出A的绝对位置;[/align] [align=left]2) 否则输出UNKNOWN。[/align] 解题代码: |
#include <set> #include <string> #include <stdio.h> using namespace std; struct Tank { int id; int x; int y; }; Tank tank[100005]; int id; set<int> tanks[100005]; FILE* fout = NULL; void insert(int m, int a, int b, int x, int y) { if (m == 1) { if (tank[b].id == -2) { tank[b].id = id++; tank[b].x = tank[b].y = 0; tanks[tank[b].id].insert(b); } if (tank[a].id >= 0) { tanks[tank[a].id].erase(a); } tank[a].id = tank[b].id; if (tank[a].id >= 0) { tanks[tank[a].id].insert(a); } tank[a].x = tank[b].x + x; tank[a].y = tank[b].y + y; } else if (m == 2) { if (tank[a].id >= 0) { tanks[tank[a].id].erase(a); } tank[a].id = -1; tank[a].x = x; tank[a].y = y; } else if (m == 3) { if (tank[a].id == -2) { insert(1, a, b, x, y); } else if (tank[b].id == -2) { insert(1, b, a, -x, -y); } else if (tank[a].id == -1 && tank[b].id == -1) { if (tank[a].x != tank[b].x + x || tank[a].y != tank[b].y + y) { fprintf(fout, "REJECT\n"); } } else if (tank[a].id == -1) { insert(4, b, -1, tank[a].x - x, tank[a].y - y); } else if (tank[b].id == -1) { insert(4, a, -1, tank[b].x + x, tank[b].y + y); } else { if (tank[a].id == tank[b].id) { if (tank[a].x != tank[b].x + x || tank[a].y != tank[b].y + y) { fprintf(fout, "REJECT\n"); } } else { int dx = tank[b].x + x - tank[a].x; int dy = tank[b].y + y - tank[a].y; int j = tank[a].id; int k = tank[b].id; for (set<int>::const_iterator itr = tanks[j].begin(); itr != tanks[j].end(); itr++) { tank[*itr].id = tank[b].id; tank[*itr].x += dx; tank[*itr].y += dy; tanks[k].insert(*itr); } set<int> temp; tanks[j].swap(temp); } } } else if (m == 4) { if (tank[a].id == -1) { if (tank[a].x != x || tank[a].y != y) { fprintf(fout, "REJECT\n"); } } else if (tank[a].id == -2) { tank[a].id = -1; tank[a].x = x; tank[a].y = y; } else { int dx = x - tank[a].x; int dy = y - tank[a].y; int j = tank[a].id; for (set<int>::const_iterator itr = tanks[j].begin(); itr != tanks[j].end(); itr++) { tank[*itr].id = -1; tank[*itr].x += dx; tank[*itr].y += dy; } set<int> temp; tanks[j].swap(temp); } } } void query(int m, int a, int b) { if (m == 5) { if (tank[a].id > -2 && tank[b].id > -2 && tank[a].id == tank[b].id) { fprintf(fout, "%d %d\n", tank[a].x - tank[b].x, tank[a].y - tank[b].y); } else { fprintf(fout, "UNKNOWN\n", m, a, b); } } else { if (tank[a].id == -1) { fprintf(fout, "%d %d\n", tank[a].x, tank[a].y); } else { fprintf(fout, "UNKNOWN\n", m, a); } } } int main() { int T, N, t = 1; int m = 0, a = 0, b = 0, x = 0, y = 0; FILE* fp = stdin; //fopen("data.in", "r"); fout = stdout; //fopen("output", "w"); fscanf(fp, "%d", &T); while (T--) { fscanf(fp, "%d", &N); for (int i = 0; i <= N; i++) { tank[i].id = -2; } id = 0; fprintf(fout, "Case #%d:\n", t++); while (N--) { fscanf(fp, "%d", &m); if (m == 1 || m == 3) { fscanf(fp, "%d %d %d %d", &a, &b, &x, &y); insert(m, a, b, x, y); } else if (m == 2 || m == 4) { fscanf(fp, "%d %d %d", &a, &x, &y); insert(m, a, b, x, y); } else if (m == 5) { fscanf(fp, "%d %d", &a, &b); query(m, a, b); } else if (m == 6) { fscanf(fp, "%d", &a); query(m, a, b); } } for (int i = 0; i < id; i++) { set<int> temp; tanks[i].swap(temp); } } }
相关文章推荐
- 2014百度之星初赛第一轮解题报告:information
- 2014百度之星初赛第一轮解题报告:party
- 2014百度之星初赛第一轮解题报告:party
- 2014百度之星初赛第一轮解题报告:CycleCocycle
- 2014百度之星初赛第一轮解题报告:CycleCocycle
- 2014百度之星初赛第一轮解题报告:grids
- 2014百度之星初赛第一轮解题报告:grids
- 【百度之星2014~初赛(第二轮)解题报告】Chess
- 2014百度之星初赛第二轮解题报告:chess
- 2014第六届华为创新杯编程大赛初赛解题报告
- 2014百度之星初赛第二轮解题报告:Scenic Popularity
- 【百度之星2014~初赛(第二轮)解题报告】Chess
- 2014百度之星初赛第二轮解题报告:Scenic Popularity
- 2014百度之星初赛第二轮解题报告:JZP set
- 2014百度之星初赛第二轮解题报告:JZP set
- 2014第六届华为创新杯编程大赛初赛解题报告
- 2014 编程之美初赛第一场(大数据) 解题报告
- 【百度之星2014~初赛解题报告】
- 【百度之星2014~初赛(第二轮)解题报告】JZP Set
- 【百度之星2014~初赛(第二轮)解题报告】JZP Set