P9840 [ICPC2021 Nanjing R] Oops, It‘s Yesterday Twice More题解

ICPC2021 Nanjing R Oops, It's Yesterday Twice More

传送门

题面翻译

有一张 n × n n\times n n×n 的网格图,每个格子上都有一只袋鼠。对于一只在 ( i , j ) (i,j) (i,j) 的袋鼠,有下面四个按钮:

  • 按钮 U:如果 i > 1 i>1 i>1,移动到 ( i − 1 , j ) (i-1,j) (i−1,j),否则,原地不动;
  • 按钮 D:如果 i < n i<n i<n,移动到 ( i + 1 , j ) (i+1,j) (i+1,j),否则,原地不动;
  • 按钮 L:如果 j > 1 j>1 j>1,移动到 ( i , j − 1 ) (i,j-1) (i,j−1),否则,原地不动;
  • 按钮 R:如果 j < n j<n j<n,移动到 ( i , j + 1 ) (i,j+1) (i,j+1),否则,原地不动。

每次按下按钮,都会对所有的 袋鼠生效。请输出一种使得所有袋鼠最终都在 ( a , b ) (a,b) (a,b) 的操作序列,并且序列的长度小于等于 3 × ( n − 1 ) 3\times(n-1) 3×(n−1)。

题目描述

After the great success in 2018, 2019, and 2020, Nanjing University of Aeronautics and Astronautics (NUAA) will host the International Collegiate Programming Contest \textit{International Collegiate Programming Contest} International Collegiate Programming Contest (ICPC) Nanjing regional for the fourth time.

Team Power of Two \textbf{\textit{Power of Two}} Power of Two and team Three Hold Two \textbf{\textit{Three Hold Two}} Three Hold Two won the champion for Tsinghua University in 2018 and 2019. In 2020, team Inverted Cross \textbf{\textit{Inverted Cross}} Inverted Cross from Peking University won the champion. In 2021, there are around 700 700 700 teams including the defending champion \textbf{the defending champion} the defending champion participating in the contest. We are so excited to see who will win this year!

Although we can't gather in Nanjing this time due to the pandemic, we should still be grateful for the hard work done by all staff and volunteers for this contest. Thank you all for your great contribution to this contest!

In the 2018 contest, problem K, Kangaroo Puzzle \textbf{\textit{Kangaroo Puzzle}} Kangaroo Puzzle, requires the contestants to construct an operation sequence for the game:

The puzzle is a grid with n n n rows and m m m columns ( 1 ≤ n , m ≤ 20 1 \le n, m \le 20 1≤n,m≤20) and there are some (at least 2 2 2) kangaroos standing in the puzzle. The player's goal is to control them to get together. There are some walls in some cells and the kangaroos cannot enter the cells with walls. The other cells are empty. The kangaroos can move from an empty cell to an adjacent empty cell in four directions: up, down, left, and right.

There is exactly one kangaroo in every empty cell in the beginning and the player can control the kangaroos by pressing the button U, D, L, R on the keyboard. The kangaroos will move simultaneously according to the button you press.

The contestant needs to construct an operating sequence of at most 5 × 1 0 4 5 \times 10^4 5×104 steps consisting of U, D, L, R only to achieve the goal.

In the 2020 contest, problem A, Ah, It's Yesterday Once More \textbf{\textit{Ah, It's Yesterday Once More}} Ah, It's Yesterday Once More, requires the contestants to construct an input map to hack the following code of the problem described before:

cpp 复制代码
#include <bits/stdc++.h>
using namespace std;
string s = "UDLR";
int main()
{
  srand(time(NULL));
  for (int i = 1; i <= 50000; i++) putchar(s[rand() % 4]);
  return 0;
}

Now in the 2021 contest, Paimon prepares another version of the problem for you. You are given a grid with n n n rows and n n n columns ( 2 ≤ n ≤ 500 2 \leq n \leq 500 2≤n≤500). All cells are empty and there is one kangaroo standing in each cell.

Similarly, you can control the kangaroos by pressing the button U, D, L, R on the keyboard. The kangaroos will move simultaneously according to the button you press. Specifically, for any kangaroo located in the cell on the i i i-th row and the j j j-th column, indicated by ( i , j ) (i,j) (i,j):

  • Button U: it will move to ( i − 1 , j ) (i-1,j) (i−1,j) if i > 1 i>1 i>1. Otherwise, it will stay in the same grid.
  • Button D: it will move to ( i + 1 , j ) (i+1,j) (i+1,j) if i < n i<n i<n. Otherwise, it will stay in the same grid.
  • Button L: it will move to ( i , j − 1 ) (i,j-1) (i,j−1) if j > 1 j>1 j>1. Otherwise, it will stay in the same grid.
  • Button R: it will move to ( i , j + 1 ) (i,j+1) (i,j+1) if j < n j<n j<n. Otherwise, it will stay in the same grid.

You need to construct an operating sequence consisting only of characters U, D, L, and R. After applying it, you must make sure every kangaroo will gather at the specific cell ( a , b ) (a,b) (a,b). The length of the operating sequence cannot exceed 3 ( n − 1 ) 3(n-1) 3(n−1).

输入格式

There is only one test case in each test file.

The first and only line of the input contains three integers n n n, a a a, b b b ( 2 ≤ n ≤ 500 2 \leq n \leq 500 2≤n≤500, 1 \\leq a,b \\leq n) indicating the size of the grid and the target cell.

输出格式

Output a string consisting only of characters U, D, L and R in one line. And its length mustn't exceed 3 ( n − 1 ) 3(n-1) 3(n−1). It can be proved that the answer always exists.

样例 #1

样例输入 #1

复制代码
3 3 3

样例输出 #1

复制代码
RRDD

样例 #2

样例输入 #2

复制代码
4 3 2

样例输出 #2

复制代码
DLDLDLUR

以上来自洛谷 以上来自洛谷 以上来自洛谷

解题思路

你以为开始讲解了?不,先听龙吟:原神,启动!(这是伏笔)

正片开始

题目中说 若越界则不动 若越界则不动 若越界则不动,就可以利用这个条件把所有袋鼠聚在一个角上,然后统一移动至目标格子,目标格子离哪个角更近就到哪个。

就结束了?不,然后这题有SPJ,要注意命令顺序。(十分的让人不爽(*******)(<-你猜猜我想说什么。))

AC Code

cpp 复制代码
#include <bits/stdc++.h>
using namespace std;
#define int long long
int n, a, b;
int tmp;
inline void work() {
	cin >> n >> a >> b;
	tmp = n / 2;
	if (a <= tmp && b <= tmp) {
		for (int i = 1; i < n; i++) {
			cout << "U";
		}
		for (int i = 1; i < n; i++) {
			cout << "L";
		}
		for (int i = 1; i < a; i++) {
			cout << "D";
		}
		for (int i = 1; i < b; i++) {
			cout << "R";
		}
	}
	if (a <= tmp && b > tmp) {
		for (int i = 1; i < n; i++) {
			cout << "U";
		}
		for (int i = 1; i < n; i++) {
			cout << "R";
		}
		for (int i = 1; i < a; i++) {
			cout << "D";
		}
		for (int i = n; i > b; i--) {
			cout << "L";
		}
	}
	if (a > tmp && b <= tmp) {
		for (int i = 1; i < n; i++) {
			cout << "D";
		}
		for (int i = 1; i < n; i++) {
			cout << "L";
		}
		for (int i = n; i > a; i--) {
			cout << "U";
		}
		for (int i = 1; i < b; i++) {
			cout << "R";
		}
	}
	if (a > tmp && b > tmp) {
		for (int i = 1; i < n; i++) {
			cout << "D";
		}
		for (int i = 1; i < n; i++) {
			cout << "R";
		}
		for (int i = n; i > a; i--) {
			cout << "U";
		}
		for (int i = n; i > b; i--) {
			cout << "L";
		}
	}
}
signed main() {
	ios::sync_with_stdio(false);
	cin.tie(0);
	cout.tie(0);
	work();
	return 0;
}
相关推荐
艾莉丝努力练剑27 分钟前
【AI大模型接入SDK】LLM会话管理模块设计
网络·c++·人工智能·学习·大模型
小此方36 分钟前
「C++AI大模型接入SDK」(一) API接入与本地两种方式对比、API Key获取、API报文详解与简单API的构建
开发语言·c++·人工智能
v_34836087628 小时前
Android native端 堆栈打印
android·算法
residual_fan8 小时前
【学术论文】航空发动机故障诊断智能体:基于持续对比强化学习的动态优化方法
人工智能·算法·数据挖掘·数据分析
GG-_-Bond9 小时前
9.1 kv存储resp协议模拟面试
c++
GreenTea9 小时前
OpenAI Agents API 上手实测:一次调用把整个 agent loop 甩给 OpenAI
前端·后端·算法
米糕闯编程9 小时前
鱼香ros2(五)用C++编写节点
c++·ros2·cmakelists·鱼香
深圳满意度咨询10 小时前
医院满意度数字化测评系统:从数据采集到智能决策的技术实践
算法
xiangyun6111 小时前
【408数据结构 08】队列:循环队列判空判满,408年年考,一次讲清
c语言·开发语言·数据结构·c++·算法
xiangyun6111 小时前
【408数据结构 06】双链表、循环链表、静态链表
c语言·开发语言·数据结构·c++·算法