蚂蚁移动⁡\operatorname{蚂蚁移动}

题目链接:ybtoj 20033⁡\operatorname{ybtoj\ 20033}ybtoj 20033

题目

有一根尺子,长度 lll,在上面有 nnn 只蚂蚁,且没有两只蚂蚁初始位置相同。每只蚂蚁有一个初始方向(左或者右),且它们会爬行,速度都是每秒一个长度单位。当它们碰到另外一个蚂蚁或者尺子的边缘时,它们会立即改变移动的方向(即反向)。

给定尺子的长度,蚂蚁的只数,以及所有蚂蚁初始的位置和方向。要你求第 ttt 秒时每只蚂蚁的位置。

输入

第一行两个整数 lllttt

第二行一个整数 NNN,表示蚂蚁的只数。

接下来的每行由两部分组成。第一部分是一个整数,表示该蚂蚁的初始位置。第二部分是一个字母,表示初始方向:D表示向右,L表示向左。两部分中间空格 .

输出

nnn 个整数,表示每只蚂蚁的最终位置。无需按照蚂蚁的原先编号输出,只要按照最终位置坐标递增(非降)的顺序输出坐标即可。

样例输入1

3 5 
1 
1 D

样例输出1

0

样例输入2

5 5 
2 
2 D 
4 L

样例输出2

1 3

样例输入3

8 10 
5 
1 L 
3 L 
4 D 
6 L 
7 D

样例输出3

1 2 4 7 7

数据范围

对于 100%100\%100% 的数据,满足 1≤n<l≤2×105,1≤n≤7×104,1≤t≤1061\leq n<l\leq 2\times10^5,1\leq n\leq 7\times10^4,1\leq t\leq 10^61n<l2×105,1n7×104,1t106

数据保证有梯度

思路

这道题是一道结论加模拟。

我们可以看到两个蚂蚁碰到就要掉头这个条件很烦,如果这个条件没有了,我们就可以枚举每一只蚂蚁最后走到哪里。

这时候你就要想:上帝啊!让这个条件消失吧!!!
然后你再去打代码的时候就算忽略了这个条件,也可以 A。

所以没了。(bushi

好了好了,正常讲:

虽然上面祈祷这个东西没用,但我们是真的可以通过一些方法得出那个条件等于不存在。

我们来看一下两个蚂蚁碰到时的不同情况:
蚂蚁移动-编程知识网
这,是一根木棍。
每一个格子,代表一个单位的长度。

第一种

蚂蚁移动-编程知识网
上一步的时候,两只蚂蚁是这样。
蚂蚁移动-编程知识网
无视碰撞,就会变成这样。
蚂蚁移动-编程知识网
这个是看碰撞的。

可以发现,在把每一个蚂蚁看成一样的时候,这两个其实是一样的。
(其实就是方向跟换了一下,又因为位置都一样, 所以可以视为不碰撞)

第二种

蚂蚁移动-编程知识网
上一步的时候,两只蚂蚁是这样。
蚂蚁移动-编程知识网
无视碰撞,就会变成这样。
蚂蚁移动-编程知识网
这个是看碰撞的。

可以发现又是一样。
(因为两个蚂蚁走到了两个点中间然后又折了回来,所以算碰撞就是两个人的方向变了,位置没变)
(而当不算碰撞的时候蚂蚁走到了对方的位置,方向又没变,而原来两只蚂蚁方向就不一样,所以就跟算碰撞一样)

所以我们就可以直接算啦~

代码

#include<cstdio>
#include<algorithm>using namespace std;int l, t, n, a[70001], nowt;
char way;int main() {
//	freopen("mravi.in", "r", stdin);
//	freopen("mravi.out", "w", stdout);scanf("%d %d\n%d", &l, &t, &n);for (int i = 1; i <= n; i++) {scanf("%d", &a[i]);way = getchar();while (way != 'D' && way != 'L') way = getchar();if (way == 'D') {//向右走nowt = t;if (t <= l - a[i]) {//不会掉头a[i] = a[i] + t;continue;}nowt -= l - a[i];a[i] = l;if (nowt / l % 2 == 1) a[i] = 0;nowt %= l;if (a[i] == 0) a[i] += nowt;else a[i] -= nowt;}else {//向左走nowt = t;if (t <= a[i]) {//不会掉头a[i] = a[i] - t;continue;}nowt -= a[i];a[i] = 0;if (nowt / l % 2 == 1) a[i] = l;nowt %= l;if (a[i] == 0) a[i] += nowt;else a[i] -= nowt;}}sort(a + 1, a + n + 1);for (int i = 1; i <= n; i++) printf("%d ", a[i]);fclose(stdin);fclose(stdout);return 0;
}