https://www.luogu.com.cn/problem/P1563
考点:模拟、高性能
题意:
题目太长,就不全贴了。大意是有n个玩具小人围成一个圈,可能朝向圈内或圈外。接下来m条指令指引我们找到最终的小人。指令告诉我们要往左边走s步或者往右边走s步。
我这里说的很笼统,具体朝内朝外向左向右还是得去看原题。
解法:
这个题用暴力会超时,主要考的就是如何用取余来代替暴力循环。
首先用一个vector存n个玩具小人的位置和名字
using PSI = pair<string, int>;
vector<PSI> v(n);
然后读取过程中我把代表朝向圈内的0改成了-1来存储,同样的道理我把代表向左的0改为-1。这样处理就可以用朝向*前进方向
来表示下标的增加或减小,积为-1可能是朝内向右走或者朝外向左走,下标是增加的;积为1同理,下标减小。
最后要用取余运算取代暴力循环,比较简单,没什么解释的,上代码。
#include <bits/stdc++.h>
using namespace std;
using PSI = pair<string, int>;
int main() {
int n,m; cin >> n >> m;
vector<PSI> v(n);
for (int i = 0; i < n; i++) { // 逆时针
cin >> v[i].second; // 0朝向圈内 1朝向圈外
if (v[i].second == 0) v[i].second = -1; // -1朝向圈内
cin >> v[i].first; // 名字
}
int now = 0; // 第一个小人
for (int i = 0; i < m; i++) {
int dir, step; cin >> dir >> step;
if (dir == 0) dir = -1; // -1左,1右
step %= (n+1); // 不管走了多少步都可以这样处理
if (dir * v[now].second < 0) { // 朝内向右或朝外向左,即下标增长
if (now + step < n) now += step;
else if (now + step == n) now = 0;
else {
step -= n - now;
now = 0;
now += step;
}
} else { // 下标减少step次
if (now - step > 0) now -= step;
else if (now - step == 0) now = 0;
else {
step -= now;
now = 0;
now += n - step;
}
}
}
cout << v[now].first;
return 0;
}