题意

有n只蚂蚁在长度为m个格子的环上,环上的格子以逆时针编号,每只蚂蚁每秒往它面向的方向移动一格。如果有两只蚂蚁相撞则相互调换方向,问t秒后每只蚂蚁的位置。

题解

首先通过观察可以发现

  • 蚂蚁相撞产生的轨迹可以看成两只蚂蚁穿过对方
  • 由于相撞后只会互相调换方向,每只蚂蚁的相对编号不会发生变化,即每只蚂蚁的“邻居”不会发生变化

也就是说:

  • 我可以通过计算每只蚂蚁毫无阻碍产生的轨迹知道t秒后哪些位置上有蚂蚁
  • 又由于每只蚂蚁的相对编号不变,我只要知道某只蚂蚁t秒后的位置就可以推算出剩下的所有蚂蚁的位置

现在的问题就由第一个问题转换成第二个问题:

  • t秒后第x个蚂蚁的位置是哪
  • t秒后第x个位置的蚂蚁编号是多少

对于第二个问题,我们只要求出t秒后蚂蚁按位置编号大小排序的序列就可以算出答案。假设一开始蚂蚁按初始位置编号的大小顺序排好,位置0(位置1与位置m的中间)是一个临界点,考虑两种情况来求出t秒后蚂蚁的顺序:

  • t秒内所有蚂蚁没有发生碰撞:当有蚂蚁从1经过0走到m时,那么这只蚂蚁就会变成最后一只蚂蚁,第二只蚂蚁会变成第一只,以此类推。同理,当有蚂蚁从m经过0走到1时,这只蚂蚁就会变成第一只蚂蚁。因此我们只要计算t秒内蚂蚁有多少次从右至左走过0点或从左至右走过0点,求差就可以得到蚂蚁在t秒后的顺序。

  • t秒内有蚂蚁发生碰撞:如果有蚂蚁发生碰撞,因为蚂蚁的轨迹可以看成穿过对方,因此我们还是可以忽略掉碰撞的情况去计算蚂蚁从两个方向通过0点的次数,就当成上面那种情况。每从右向左通过0点一次,蚂蚁的排列序列就左移一次,向右同理。

举个例子,假如一开始蚂蚁编号的排列顺序为[1,3,2],在某一秒2从m点通过了0点到1点,序列变成[2,1,3]。假如2与1发生碰撞,2再次反向通过0点,排列顺序又变回[1,3,2]。看上去好像要判断蚂蚁2从不同方向经过了0点,但是我们完全可以忽略碰撞看成蚂蚁2从左边经过了一次0点和蚂蚁1从右边经过了一次0点,对于复杂的情况也完全适应。

此时我们已知:

  • t秒后那些位置上有蚂蚁
  • t秒后蚂蚁按位置的排序

我们就可以直接一一对应上蚂蚁的位置了

#include<bits/stdc++.h>
using namespace std;
#define rep(i, a, b) for(int i=(a); i<(b); i++)
#define per(i, a, b) for(int i=(a-1); i>=(b); i--)
typedef long long ll;
const int maxn = 300005;
const int inf = 0x3f3f3f3f;
struct A {
ll pos;
char f;
bool operator<(const A &x) const {
return pos < x.pos;
}
}a[maxn];
int id[maxn], ans[maxn];
int main()
{
std::ios::sync_with_stdio(false);
std::cin.tie(0);
ll n, m, t;
cin >> n >> m >> t;
int offset = 0;
rep(i, 0, n) {
id[i] = i;
cin >> a[i].pos >> a[i].f;
a[i].pos--;
}
//排序得到蚂蚁的初始排列
sort(id, id + n, [&](int x, int y) { return a[x].pos < a[y].pos; });
//计算蚂蚁t秒后的排列,顺便算出t秒后哪些位置出现了蚂蚁
rep(i, 0, n) {
if (a[i].f == 'L') {
offset = (offset + (a[i].pos - t - m + 1) / m) % n;
a[i].pos = ((a[i].pos - t)%m + m) % m;
}
else {
offset = (offset + (a[i].pos + t) / m) % n;
a[i].pos = (a[i].pos + t) % m;
}
}
offset = (offset + n) % n;
//对位置排序
sort(a, a + n);
//此时初始次序为i编号为id[x]的蚂蚁在t秒后变成了次序为(i+offset)%n的蚂蚁
rep(i, 0, n) ans[id[i]] = a[(i + offset)%n].pos + 1;
rep(i, 0, n) cout << ans[i] << ' ';
return 0;
}

Codeforces 652F 解题报告的更多相关文章

  1. Codeforces 524 解题报告

    打的很快乐的一次比赛hiahiahia, 才A掉4题rating就涨了100+ 距离比赛\(3\)天了, 由于博主实在太颓, 又补掉了\(E\)题, 到现在才发解题报告 A. 语法题, 读入输出就行了 ...

  2. codeforces 714C解题报告

    http://codeforces.com/contest/714/problem/C #include <bits/stdc++.h>//非递归形式建立字典树 using namespa ...

  3. codeforces#254DIV2解题报告

    今天简直大爆发啊... 吃了顿烧烤竟然这么管事. . . .. 本弱渣竟然做出来了3道,并且B题是我第一次在CF中用到算法..(曾经最多也就是贪心. . . ). 题目地址:codeforces#22 ...

  4. codeforces 476C.Dreamoon and Sums 解题报告

    题目链接:http://codeforces.com/problemset/problem/476/C 题目意思:给出两个数:a 和 b,要求算出 (x/b) / (x%b) == k,其中 k 的取 ...

  5. Codeforces Round #378 (Div. 2) D题(data structure)解题报告

    题目地址 先简单的总结一下这次CF,前两道题非常的水,可是第一题又是因为自己想的不够周到而被Hack了一次(或许也应该感谢这个hack我的人,使我没有最后在赛后测试中WA).做到C题时看到题目情况非常 ...

  6. Codeforces Round 665 赛后解题报告(暂A-D)

    Codeforces Round 665 赛后解题报告 A. Distance and Axis 我们设 \(B\) 点 坐标为 \(x(x\leq n)\).由题意我们知道 \[\mid(n-x)- ...

  7. Codeforces Round 662 赛后解题报告(A-E2)

    Codeforces Round 662 赛后解题报告 梦幻开局到1400+的悲惨故事 A. Rainbow Dash, Fluttershy and Chess Coloring 这个题很简单,我们 ...

  8. Codeforces Educational Round 92 赛后解题报告(A-G)

    Codeforces Educational Round 92 赛后解题报告 惨 huayucaiji 惨 A. LCM Problem 赛前:A题嘛,总归简单的咯 赛后:A题这种**题居然想了20m ...

  9. Codeforces Round #382 (Div. 2) 解题报告

    CF一如既往在深夜举行,我也一如既往在周三上午的C++课上进行了virtual participation.这次div2的题目除了E题都水的一塌糊涂,参赛时的E题最后也没有几个参赛者AC,排名又成为了 ...

随机推荐

  1. [线段树]Luogu P3372 线段树 1【模板】

    #include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #d ...

  2. EasyUIDataGrid列标题换行显示

    有时候表格标题字数太多,而宽度有限,就会导致一部分列的标题显示不出来 这时候,加入如下css代码即可将标题换行显示 .datagrid-header-row .datagrid-cell span { ...

  3. 关于 C# 8.0 的 Switch Case When 的用法

    直接贴代码了: static void Main(string[] args) { SwitchSample(); } private static void SwitchSample() { Swi ...

  4. 【UOJ#61】【UR #5】怎样更有力气(最小生成树)

    [UOJ#61][UR #5]怎样更有力气(最小生成树) 题面 UOJ 题解 最最最暴力的想法是把所有边给处理出来然后跑\(MST\). 考虑边权的情况,显然离线考虑,把么一天按照\(w_i\)进行排 ...

  5. Winform中设置ZedGraph的字体和间距不随图形的缩放而缩放

    场景 C#窗体应用中使用ZedGraph曲线插件绘制图表: https://blog.csdn.net/BADAO_LIUMANG_QIZHI/article/details/99716066 Win ...

  6. maven 学习---部署基于Maven的war文件到Tomcat

    在本教程中,我们将学习如何使用Maven的Tomcat插件打包并部署一个WAR文件到Tomcat(Tomcat的6和7. 要用到工具: Maven 3 Tomcat 6.0.37 Tomcat 7.0 ...

  7. Jmeter-While控制器

    Jmeter-While控制器 背景: 用作循环的控制器里, 最常用的就’循环控制器’和’While控制器’. 循环控制器仅能定义循环次数(永远和自定义次数). 缺乏判断能力.While控制器正好弥补 ...

  8. ThinkPHP删除目录及目录下文件的函数【转】

    1.删除目录及目录下所有的文件 2.删除目录下的所有文件但目录结构保留 3.删除指定文件 贴代码 /** +---------------------------------------------- ...

  9. [TCP/IP] TCP如何保证可靠性

    1.数据包校验,发送方计算校验和,接收方结算校验和,进行对比2.应答机制,seq序列号与ack确认号 3.超时重传机制,发送后启动定时器,进行重传 4.连接管理,三次和四次5.对失序数据包重排序6.流 ...

  10. vm|vmware workstation 15|14 pro 激活|密钥|序列号|许可证

    VMware Workstation Pro 15 激活许可证 UY758-0RXEQ-M81WP-8ZM7Z-Y3HDA VF750-4MX5Q-488DQ-9WZE9-ZY2D6 UU54R-FV ...