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;
}
相关推荐
RuoZoe5 小时前
重塑WPF辉煌?基于DirectX 12的现代.NET UI框架Jalium
c语言
blasit7 小时前
笔记:Qt C++建立子线程做一个socket TCP常连接通信
c++·qt·tcp/ip
AI软著研究员7 小时前
程序员必看:软著不是“面子工程”,是代码的“法律保险”
算法
FunnySaltyFish7 小时前
什么?Compose 把 GapBuffer 换成了 LinkBuffer?
算法·kotlin·android jetpack
颜酱8 小时前
理解二叉树最近公共祖先(LCA):从基础到变种解析
javascript·后端·算法
地平线开发者1 天前
SparseDrive 模型导出与性能优化实战
算法·自动驾驶
董董灿是个攻城狮1 天前
大模型连载2:初步认识 tokenizer 的过程
算法
地平线开发者1 天前
地平线 VP 接口工程实践(一):hbVPRoiResize 接口功能、使用约束与典型问题总结
算法·自动驾驶
罗西的思考1 天前
AI Agent框架探秘:拆解 OpenHands(10)--- Runtime
人工智能·算法·机器学习
HXhlx1 天前
CART决策树基本原理
算法·机器学习