题目描述
P1563 [NOIP2016 提高组] 玩具谜题
前置知识
无
题目分析
题目比较绕,关键是要搞清楚顺时针、逆时针和左、右,把每个指令转换为数组下标的移动。
首先提取出关键信息:
输入顺序为逆时针
面朝圈内:左->顺时针,右->逆时针
面朝圈外:左->逆时针,右->顺时针
判断每一步移动的步骤:
取得指令方向 → 取得当前朝向 → 得出下标变化方向
关键是最后一步,需要分情况讨论。对于分类讨论,列表分析是最合适的方法。
另附示例 1 的分析图:
至于怎么模拟这个“圈”,可以使用取余运算实现。
具体见代码。
参考答案
Java:
import java.util.*;
class Person {
public final static int OUTER = 0; // 圈内
public final static int INNER = 1; // 圈外
public int direction;
public String name;
@Override
public String toString() {
return name + " " + direction;
}
}
class Command {
public final static int LEFT = 0;
public final static int RIGHT = 1;
public int direction;
public int step;
@Override
public String toString() {
return direction + " " + step;
}
}
public class Main {
private static ArrayList<Person> persons = new ArrayList<Person>();
private static ArrayList<Command> commands = new ArrayList<Command>();
public static void main(String[] args) {
// 输入
Scanner s = new Scanner(System.in);
int n = 0; // 小人个数
int m = 0; // 指令个数
n = Integer.parseInt(s.next());
m = Integer.parseInt(s.next());
// 输入小人
for (int i = 0; i < n; i++) {
Person p = new Person();
p.direction = Integer.parseInt(s.next());
p.name = s.next();
persons.add(p);
}
// 输入指令
for (int i = 0; i < m; i++) {
Command c = new Command();
c.direction = Integer.parseInt(s.next());
c.step = Integer.parseInt(s.next());
commands.add(c);
}
// System.out.println("Person: " + persons);
// System.out.println("Command: " + commands);
// 求解
System.out.println(solve());
}
private static String solve() {
int index = 0;
// 题目分析部分提到的表的代码实现
for (Command c : commands) {
Person p = persons.get(index);
if (c.direction == Command.LEFT) {
if (p.direction == Person.OUTER)
index -= c.step;
else
index += c.step;
}
else {
if (p.direction == Person.OUTER)
index += c.step;
else
index -= c.step;
}
// 实现下标循环
index = (index + persons.size()) % persons.size();
}
return persons.get(index).name;
}
}
C++:
(由 ChatGPT 转换)
#include <iostream>
#include <vector>
#include <string>
class Person {
public:
static const int OUTER = 0; // 圈内
static const int INNER = 1; // 圈外
int direction;
std::string name;
};
class Command {
public:
static const int LEFT = 0;
static const int RIGHT = 1;
int direction;
int step;
};
int main() {
std::vector<Person> persons;
std::vector<Command> commands;
// 输入
int n, m;
std::cin >> n >> m;
// 输入小人
for (int i = 0; i < n; i++) {
Person p;
std::cin >> p.direction >> p.name;
persons.push_back(p);
}
// 输入指令
for (int i = 0; i < m; i++) {
Command c;
std::cin >> c.direction >> c.step;
commands.push_back(c);
}
// 求解
std::cout << solve(persons, commands) << std::endl;
return 0;
}
std::string solve(std::vector<Person>& persons, std::vector<Command>& commands) {
int index = 0;
for (const Command& c : commands) {
Person& p = persons[index];
if (c.direction == Command::LEFT) {
if (p.direction == Person::OUTER)
index -= c.step;
else
index += c.step;
}
else {
if (p.direction == Person::OUTER)
index += c.step;
else
index -= c.step;
}
// 实现下标循环
index = (index + persons.size()) % persons.size();
}
return persons[index].name;
}