【题解】[NOIP2016]玩具谜题

题目描述

P1563 [NOIP2016 提高组] 玩具谜题

前置知识

题目分析

题目比较绕,关键是要搞清楚顺时针、逆时针和左、右,把每个指令转换为数组下标的移动。

首先提取出关键信息:

输入顺序为逆时针
面朝圈内:左->顺时针,右->逆时针
面朝圈外:左->逆时针,右->顺时针

判断每一步移动的步骤:
取得指令方向 → 取得当前朝向 → 得出下标变化方向

关键是最后一步,需要分情况讨论。对于分类讨论,列表分析是最合适的方法。
【题解】[NOIP2016]玩具谜题_第1张图片

另附示例 1 的分析图:
【题解】[NOIP2016]玩具谜题_第2张图片

至于怎么模拟这个“圈”,可以使用取余运算实现。
具体见代码。

参考答案

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 
#include 
#include 

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;
}

你可能感兴趣的:(算法:题解,java,c++,算法,开发语言,c语言)