A:超级闪光牛可乐 链接
题目描述
森林中出现了野生的超级闪光牛可乐口牙! 虽然我们不能为每一位参赛选手提供超级闪光牛可乐,但是……参加小白月赛且有通过题目的选手,第一名,前50名抽1人,51-200名抽2人,201名之后每100人抽1名,赠送牛可乐U型枕!
森林中出现了野生的超级闪光牛可乐!想要捕捉它,你至少需要投喂 x 点诱惑力的食物。幸运的是,清楚姐姐在知道了这件事后,非常大气的为你开放了她的豪华零食仓库——仓库里有 n 种不同名称的食物,第 i 种食物能提供 wi点的诱惑力。当你所投喂食物的诱惑力之和不小于 x 时,就可以顺利的捕捉到它。
现在,你可以从仓库中取走一些食物了,不管怎么说,今天的目标只有一个,那就是拿下超级闪光牛可乐!
输入描述: 每个测试文件仅有一组测试数据。 第一行输入一个整数 x (1 <= x <= 1000) 表示至少需要多少诱惑力的食物才能捕捉这一只超级闪光牛可乐 第二行输入一个整数 n (1 <= n <= 26) 表示清楚姐姐豪华零食仓库中的零食种类数量。 随后 n 行,每行输入一个小写字母 ch 和一个整数 w (‘a’≤ch ≤ ‘z’, 1 <= w <= 500) 表示第 i 种零食的名称以及提供的诱惑力。保证零食的名称不重复;使用单个空格间隔。
输出描述: 需要在一行上输出一个由小写字母组成的答案字符串,代表你要喂给超级闪光牛可乐的食物。 注意,喂食的零食数量不能超过 1000 个,否则牛可乐会因为吃不下而直接离开。 楚姐姐仓库中没有的零食种类提供的诱惑力会被视为 0 。 果无法捕获牛可乐,仅需输出一行 −1 。
示例1
输入 复制
输出 复制
说明 在这个样例中,你至少需要 诱惑力的食物才能捕捉这一只超级闪光牛可乐,而一个名称为 c 的零食就可以提供 3 诱惑力,所以你只需要投喂两个 c 。当然,另外一种可行的投喂方式是投喂六个 q 。
示例2
输入 复制
输出 复制
说明 1 在这个样例中,投喂的食物一共能够提供 5 点诱惑力,足够捕捉这只超级闪光牛可乐。
备注:
代码 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 #include <iostream> #include <algorithm> using namespace std;typedef pair<char , int > PII;const int N = 30 ;int n, x; PII a[N];bool cmp (PII X,PII Y) { return X.second > Y.second; }int main () { ios::sync_with_stdio (false ),cin.tie (0 ),cout.tie (0 ); cin >> x >> n; for (int i = 0 ; i < n; i++) { char c; int k; cin >> c >> k; a[i] = {c, k}; } sort (a, a + n, cmp); int kk = x / a[0 ].second; if (kk > 1000 ) cout << "-1" ; for (int i = 0 ; i < kk; i++) cout << a[0 ].first; if (x % a[0 ].second != 0 ) cout << a[0 ].first; return 0 ; }
B:人列计算机 链接
题目描述 人列计算机是一种用人来模拟计算机的逻辑运算的装置,它最早出现在刘慈欣的科幻小说《三体》中。在小说中,冯·诺伊曼向秦始皇介绍了用三千万秦兵组成人列计算机的计划,目的是解决三体问题。 这一计算机的原理其实非常的朴实无华,即使用人来代替电子元件:用黑白旗来代表二进制的 0 和 1 ,用不同的举旗方式来实现与、或、非等基本逻辑运算,从而构成一个巨大的计算系统。 现在,让我们来介绍一下什么是门电路。如下图所示, # 号(Ascii:35)代表门电路的轮廓: 在与门电路中,字符 A 与 B 代表输入,井号矩形内部的 & 号(Ascii:38)代表这是一个与门。 在或门电路中,字符 A 与 B 代表输入,井号矩形内部的 >=1 代表这是一个或门。
输入描述: 1 2 每个测试文件仅有一组测试数据。 我们保证,A 与 B 的值仅可能为 0 或者 1 ;输入为严格的 5 行 10 列,空白部分均使用空格填充。
输出描述: 1 对于给定的逻辑门图像,输出一个整数代表运算过后的结果。
示例1
输入 复制
1 2 3 4 5 **** * 1*** * * & ** * 1*** * ** ***
输出 复制
说明 $$ 在这个样例中,我们需要计算 1 和 1 进行与操作运算过后的结果,查阅上方的表格可以很容易的得到,答案为 1。 $$
示例2
输入 复制
1 2 3 4 5 **** * 0*** * *>=1* ** 1*** * ** ***
输出 复制
示例3
输入 复制
1 2 3 4 5 **** * * * 1*** 1 *O* * * ** ***
输出 复制
备注: 如果你不熟悉逻辑门的运算原理,那么让我们一起来了解一下。 如果是与门,你需要输出 A 和 B 进行与运算后的结果;如果是或门,你需要输出 A 和 B 进行或运算后的结果;如果是非门,你需要输出 A 进行非运算后的结果,基本的计算方式可以参考下图。如果您需要更多位运算相关的知识,可以参考 OI-Wiki上的相关章节(点击可跳转)。
代码 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 #include <bits/stdc++.h> using namespace std; string a[15 ];int n,kk;int b[2 ];int main () { int k = 0 ; for (int i = 0 ; i < 5 ; i++) { getline (cin,a[i]); } int x, y; if (a[1 ][0 ] != ' ' ) { x = a[1 ][0 ] - '0' ; y = a[3 ][0 ] - '0' ; } else { x = a[2 ][0 ] - '0' ; } if (a[2 ][5 ] == '&' ) { cout << (x && y); } else if (a[2 ][5 ] == '=' ) { cout << (x || y); } else { cout << !x; } return 0 ; }
C:时间管理大师 链接
题目描述
制定合理的日程能够帮助利用好时间进行加训,加训和加训。 新学期开始了,应该好好学习了!凌晨两点整,加睡失败的你在为新一天的各项重要事件制定闹钟。
$$
你的手上有一张日程表,上面列出了一些事件发生的时间。你想在每一个日程事件开始前 1, 3 和 5 分钟各设定一个闹钟, 最后,将这些闹钟按照时间先后顺序依次输出(就像你在手机闹钟界面看到的一样)。 注意,如果有多个闹钟被设定在同一时间,那么它们会被视为同一个。 正式地,假设闹钟 a 将在 h_a 时 m_a分响起,闹钟 b 在 h_b 时 m_b 分响起,那么:
如果 h_a<h_b,闹钟 a 先于闹钟 b 响起;
当h_a=h_b 时, 如果m_a<m_b ,闹钟 a 先于闹钟 b 响起;
当 h_a=h_b 时, 如果 m_a=m_b,闹钟 a 和闹钟 b 应当被看作同一个闹钟。
输入描述: $$ \begin{flalign} &每个测试文件仅有一组测试数据。\\ &第一行输入一个整数n(1< n < 1000)表示日程的数量。\\ &随后n行,第i行输入两个整数h_i,和m_i(3≤h,≤23,0≤m≤59)表示第i个日程\\ &开始的时分(采用24小时制),数字不包含前导零。注意可能有多个日程事件开始于同一时刻。&\\ \end{flalign} $$
输出描述: $$ \begin{flalign} &第一行输出一个整数m,代表设定的闹钟数量。\\ &随后m行,第i行输出两个由单个空格分隔的整数h_i’和m_i’(0≤h_i≤23,0≤m_i≤59),\\ &代表第i个闹钟在h_i’;时m_i’分响起。数字不应当包含前导零。&\\ \end{flalign} $$ 示例1
输入 复制
输出 复制
说明 1 2 3 第一个日程事件开始于 03:05 ,我们需要在 03:00 、03:02 和 03:04 这三个时刻各设置一个闹钟。 第二个日程事件开始于 03:03 ,我们需要在 02:58 、03:00 和 03:02 这三个时刻各设置一个闹钟。 注意到 03:00 和 03:02 这两个时刻都被设置了两个闹钟,需要将它们看成同一个,最终共需设定四个闹钟。
代码一 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 #include <iostream> #include <set> using namespace std;typedef pair<int , int > PII;const int N = 1010 ;class Mycompare {public : bool operator () (PII v1, PII v2) { return v1.first < v2.first || (v1.first == v2.first && v1.second < v2.second); } }; set<PII, Mycompare> p;int n;bool cmp (PII X, PII Y) { return X.first < Y.first || (X.first == Y.first && X.second < Y.second); }int main () { ios::sync_with_stdio (false ),cout.tie (0 ),cin.tie (0 ); cin >> n; for (int i = 1 ; i <= n; i++) { int h, m; cin >> h >> m; if (m >= 5 ) { int kk = m - 5 ; p.insert ({h, kk}); } if (m >= 3 ) { int kk = m - 3 ; p.insert ({h, kk}); } if (m >= 1 ) { int kk = m - 1 ; p.insert ({h, kk}); } if (m < 5 ) { int xx = h - 1 ; int kk = m - 5 + 60 ; p.insert ({xx, kk}); } if (m < 3 ){ int xx = h - 1 ; int kk = m - 3 + 60 ; p.insert ({xx, kk}); } if (m < 1 ) { int xx = h - 1 ; int kk = m - 1 + 60 ; p.insert ({xx, kk}); } } cout << p.size () << '\n' ; for (auto item:p) cout << item.first << " " << item.second << '\n' ; return 0 ; }
D:我不是大富翁 链接
题目描述
提到大富翁游戏!就想到环!!就想到经典的约瑟夫问题!!!作为经典问题,其出彩的展示了数学思维在实际问题中的应用,启发了一代又一代的算竞人。 好了,不要再约瑟夫了,都是经典问题害的你,没法正常的玩大富翁游戏。现在,让我们来愉快的玩大富翁吧!,
Rabbit\rm\mathcal RabbitRabbit 拿到了一张环形的大富翁地图,地图被平均划分为了 nnn 个地块,地块的编号以 1 为起点,顺时针进行排布。即 111 号地块的顺时针方向依次为 2, 3,… 号地块;111 号地块的逆时针方向依次为 n, n−1\dot 号地块(由于是环形的,所以 111 号地块与 n 号地块相邻,如下图所示)。
游戏过程如下:系统会给定一个长度为 m 的行动力序列 a_1,a_2,\dots,a_m ,在第 i (1≤i≤m) 回合,Rabbit都需要移动 aia_iai 个地块,但是他可以自由选择移动的方向(换句话说,可以自由选择是向逆时针还是顺时针方向移动 aia_iai 个地块)。 在游戏的开始时,Rabbit 位于 1 号地块,他想知道是否存在这样一种移动方式,使得 m 个回合后他依旧在 1 号地块。
输入描述: $$ \begin{flalign} &每个测试文件仅有一组测试数据。\\ &第一行输入两个整数 n 和 m ( 1≤n, m≤5000) 表示地块数量和行动回合数。\\ &第二行输入 m 个整数 a_1,a_2,\dots,a_m (0\le a_i\le 2 \cdot 10^5) 表示行动力序列。&\\ \end{flalign} $$
输出描述: $$ \begin{flalign} &如果 m 个回合后 Rabbit依旧在 1 号地块,则输出 YES ;否则,请输出 NO。\\ &您可以以任何大小写形式输出答案,例如,yEs\ yes\ 和\ YeS\ 视为肯定的回答。& \\ \end{flalign} $$
示例1
输入 复制
输出 复制
示例2
输入 复制
输出 复制
示例3
输入 复制
输出 复制
备注: 如果您需要使用 Python 解题,我们建议您在提交时选择 pypy2 或 pypy3 。
思路 菜鸟一个,写个个人代码题解 下面的部分都是本人的个人理解,如果有错误,请大家斧正。 首先,这道题目可以理解为解决这么一个问题:如果我们想让Rabbit的最终位置在1保持不变,那么此时我们这样思考,我们现在假设Rabbit现在已经到达了最终的目的地同时还是1这个位置,也就是保持不动,那么我们可以到达这个位置的条件是什么呢?实际上就是距离你位置1距离为a[m]的位置是否存在上一次跳转的记录(实际上也就是上一次你在进行第m-1次跳转的之后可能到达位置的记录 ),我来举个例子,就以题目示例1举例子:\
360 3 120 120 120
一开始你的位置就是1,但是为了方便计算,我们实际上可以将这个图变为0~n-1的图像,这个地方应该可以理解到,后面的代码大家就知道为什么需要这样变了。 一开始你在位置0,那么你可以跳到的位置就是 ((0 + 120) % 360) 和 ((0 - 120 % 360) + 360) % 360 两个位置, 那么我们就给这两个位置设置为为1,表示的是我走第一步可以走到的位置,实际公式: f[(0 + k) % n] = 1,f[((0-k % n) + n) % n] = 1; 那么我们在下一步需要寻找我们可以跳到哪些位置就可以通过枚举0 ~ n - 1的位置,找一下判断一下第1次可以走到的位置,然后将第1次可以走到的位置继续顺时针走一下a[2],再逆时针走一下a[2]看看可以走到哪些位置,然后将这些位置记录为2,表示这些位置是Rabbit第2次走到的。依次类推,第3次想看看可以跳到哪些位置,就只需要看看第2次我们跳到哪里去了,然后通过第2次跳到的位置找到我们第3次可以跳到的地方,记录=3,下面直接来看下:
代码一 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 #include <iostream> using namespace std;const int N = 5010 ;int f[N][N];int n, m; int main () { ios::sync_with_stdio (false ),cin.tie (0 ),cout.tie (0 ); cin >> n >> m; int k; cin >> k; f[1 ][k % n] = 1 ; f[1 ][((-k % n) + n) % n] = 1 ; for (int i = 2 ; i <= m; i++) { int x; cin >> x; for (int j = 0 ; j < n; j++) { if (f[i - 1 ][j] == i - 1 ) { f[i][(((j + x) % n) + n) % n] = i; f[i][(((j - x) % n) + n) % n] = i; } } } if (f[m][0 ] == m) cout << "YES" ; else cout << "NO" ; return 0 ; }
这段代码的内存消耗还是蛮大的,我们现在来尝试一下是否可以优化一下空间,将二维转直接变为一维,对于本人的这种写法本人觉得应该是不可以直接转为一维的,因为如果转为一维这里更新的时候就会变成这个样子:\
1 2 3 4 if (f[j] == i - 1 ) { f[(((j + x) % n) + n) % n] = i; f[(((j - x) % n) + n) % n] = i; }
如此你此时就可能会造成它还没有遍历到的第j个位置的位置f[j] = i,这样就会造成第i - 1次跳跃可能达到情况有损失了,所以这里是不允许直接转换为一维的,但是我们可以通过滚动数组的方式来优化一下。
代码二 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 #include <iostream> using namespace std;const int N = 5010 ;int f[2 ][N];int n, m; int main () { ios::sync_with_stdio (false ),cin.tie (0 ),cout.tie (0 ); cin >> n >> m; int k; cin >> k; f[0 ][k % n] = 1 ; f[0 ][((-k % n) + n) % n] = 1 ; for (int i = 2 ; i <= m; i++) { int x; cin >> x; for (int j = 0 ; j < n; j++) { if (f[i % 2 ][j] == i - 1 ) { f[(i + 1 ) % 2 ][(((j + x) % n) + n) % n] = i; f[(i + 1 ) % 2 ][(((j - x) % n) + n) % n] = i; } } } if (f[(m + 1 ) % 2 ][0 ] == m) cout << "YES" ; else cout << "NO" ; return 0 ; }
代码一(二维,200ms or so,98400kb) 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 #include <iostream> using namespace std;const int N = 5010 ;int f[N][N];int n, m;int main () { ios::sync_with_stdio (false ),cin.tie (0 ),cout.tie (0 ); cin >> n >> m; int k; cin >> k; f[1 ][(0 + k) % n] = 1 ; f[1 ][(((0 - k) % n) + n) % n] = 1 ; for (int i = 2 ; i <= m; i++) { int x; cin >> x; for (int j = 0 ; j < n; j++) { if (f[i - 1 ][j] == i - 1 ) { f[i][(((j + x) % n) + n) % n] = i; f[i][(((j - x) % n) + n) % n] = i; } } } if (f[m][0 ] == m) cout << "YES" ; else cout << "NO" ; return 0 ; }
代码二(DP + 滚动数组,130ms左右,504kb) 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 #include <iostream> using namespace std;const int N = 5010 ;int f[2 ][N];int n, m; int main () { ios::sync_with_stdio (false ),cin.tie (0 ),cout.tie (0 ); cin >> n >> m; int k; cin >> k; f[1 ][k % n] = 1 ; f[1 ][((-k % n) + n) % n] = 1 ; for (int i = 2 ; i <= m; i++) { int x; cin >> x; for (int j = 0 ; j < n; j++) { if (f[(i + 1 ) % 2 ][j] == i - 1 ) { f[i % 2 ][(j + x) % n] = i; f[i % 2 ][(((j - x) % n) + n) % n] = i; } } } if (f[m % 2 ][0 ] == m) cout << "YES" ; else cout << "NO" ; return 0 ; }
E:多重映射 链接
题目描述
在书写代码时,我们时常会使用到批量查找替换的功能。现在,我们需要对一些数字进行类似的操作。 (本题没有题图,因为说话的人在映射后丢失了!)
$$ \begin{flalign} &已知一个由数字构成的序列 A ,不妨定义一个函数 M(x)=y 表示将序列 A 中全部的数字 x 都替换为 y 。例如 &A={ 2,2,4,5,1,4} \\ &执行一次 M(2)=1 操作后,序列变为 A′={1,1,4,5,1,4} ,很神奇吧!\\ &这样的替换显然是能够进行反复叠加的,\\ &举例说明,对于上方操作过后的 A′再执行一次 M(1)=2 操作,序列会变为 A′′={2,2,4,5,2,4} 。\\ &现在,给出若干个这样的操作,请你输出修改过后的序列。& \\ \end{flalign} $$
输入描述: $$ \begin{flalign} &每个测试文件均包含多个测试点。第一行输入一个整数 T (1≤T≤10^5) 代表测试数据组数,每组测试数据描述如下:\\ &第一行输入两个整数 n 和 m (1≤n,m≤10^5) 表示序列长度和操作数量。\\ &第二行输入 n 个整数 a_1,a_2,…,a_n(1≤a_i≤10^6) 表示给定的序列。\\ &此后 m 行,第 i 行输入两个整数 x_i 和 y_i (1≤x_i,y_i\le10^6) 表示一个操作。\\ &保证所有测试用例的 n 之和不会超过 2⋅10^5 ,m 之和不会超过 2⋅10^5。& \end{flalign} $$
输出描述: 1 对于每组数据,你都需要在一行上输出 n 个整数,代表执行操作后的序列,数字彼此间通过单个空格间隔。
示例1
输入 复制
1 2 3 4 5 6 7 8 2 6 1 2 2 4 5 1 4 2 1 6 2 2 2 4 5 1 4 2 1 1 6
输出 复制
说明
示例2
输入 复制
1 2 3 4 5 6 7 8 1 3 5 20 17 18 8 16 15 1 20 2 20 1 15 1
输出 复制
备注:
代码(并查集) 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 #include <iostream> #include <cstring> using namespace std;const int N = 1e6 + 10 ;int a[N],p[N], l[N], r[N];int T,n, m;int main () { ios::sync_with_stdio (false ),cin.tie (0 ),cout.tie (0 ); cin >> T; while (T--) { cin >> n >> m; for (int i = 1 ; i <= n; i++) { cin >> a[i]; p[a[i]] = a[i]; } for (int i = 1 ; i <= m; i++) { cin >> l[i] >> r[i]; p[l[i]] = l[i]; p[r[i]] = r[i]; } for (int i = m; i >= 0 ; --i) { p[l[i]] = p[r[i]]; } for (int i = 1 ; i <= n; i++) { a[i] = p[a[i]]; cout << a[i]<< " " ; } cout << '\n' ; } return 0 ; }
F:现在是消消乐时间 链接
题目描述
方块消除游戏是一种益智类的游戏,它的玩法是通过射出小球来消除屏幕上的方块,小球在移动过程中会碰撞并消除所遇到的方块,当遇到墙壁时则会反弹。
现在,我们有一个简化版本的方块消除游戏,它的具体规则描述如下:
整个游戏在一个 n 行 m 列的矩形中进行。矩形的底部 d 行 m 列为空白单元格,其余位置放置着可被消除的方块,每个方块占据一个单元格,方块的中心点和单元格的中心点重合;
矩形底部空白区域中 d+1 条横线与竖线相交形成的 (d+1)×(m+1) 个交点为合法的小球发射地点,你可以在这些交点中任选一个作为发射地点,随后,从左上 45^∘^ 、右上 45^∘^ 、左下 45^∘^ 、右下 45^∘^ 这四个方向中选择一个方向射出小球;
小球在移动过程中会沿着射出的方向运行,当其碰到任意一个方块的中心时,会将其消除;当其碰到墙壁后,会发生反弹。
我们进一步的规定这里的反弹所代表的含义:
如果小球射向矩形的四个角,那么游戏直接结束;
否则,如果小球碰到矩形左侧或右侧边缘,那么小球的水平方向(x轴)的速度会变为相反数,垂直方向(y轴)的速度不变,即小球的运动方向会沿着垂直于墙壁的方向反射;
如果小球碰到矩形上方或下方边缘,那么小球的垂直方向(y轴)的速度会变为相反数,水平方向(x轴)的速度不变,即小球的运动方向会沿着水平于墙壁的方向反射。
现在, Salt 想要知道,是否存在这样一个发射地点,使得小球射出后能够消除全部的方块。
输入描述: 1 2 每个测试文件仅有一组测试数据。 第一行输入三个整数 n , m 和 d (1 ≤n , m≤2000 , 0 ≤d≤n0 ) 表示游戏矩形网格的行数、列数以及空白占据的行数。
输出描述: $$ \begin{flalign} &如果存在这样的发射地点,首先输出一行 \rm YES ,接下来在第二行输出两个整数 x 和 y (0 \le x \le d, 0≤y≤m) \\ &表示发射地点所在的横线编号与竖线编号,在第三行输出小球的发射方向:\\ &如果向左上 45^{\circ} 方向射出小球,输出 \rm {UL} ;\\ &如果向右上 45^{\circ} 方向射出小球,输出 \rm {UR} ;\\ &如果向左下 45^{\circ} 方向射出小球,输出 \rm{DL} ;\\ &如果向右下 45^{\circ} 方向射出小球,输出 \rm{DR} 。\\ &如果不存在这样的发射地点,仅需输出一行 \rm {NO} 。你可以以任何大小写形式输出答案。& \\ \end{flalign} $$
示例1
输入 复制
输出 复制
说明 1 在第一个样例中,我们一共有 16 种不同的发射情况,如下图所示(其中蓝色箭头代表发射方向)。由于这 16 种情况均无法一次性消除全部的方块,故我们输出 NO 。
示例2
输入 复制
输出 复制
说明 1 在第二个样例中,存在多种发射方式使得小球能够一次性消除全部方块,我们在此仅展示其中一种。
备注:
代码 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 n,***p(int ,input ().strip().split()) D *= 2 corner = set () corner.add((0 ,0 )) corner.add((0 ,m)) corner.add((n,0 )) corner.add((n,m))def getRes (start,xc,yc ): x,y = start t = 0 while True : while 0 <= x+xc <= n and 0 <= y+yc <= m: nx,ny = x+xc,y+yc if x+nx >= D: t += 1 x,y = nx,ny if not y: yc *= -1 elif not x: xc *= -1 elif y == m: yc *= -1 else : xc *= -1 if (x,y) in corner or (x,y) == start: return t == m * (n-D//2 )if getRes((0 ,0 ),1 ,1 ): print ("YES" ) print (0 ,0 ) print ("UR" )elif getRes((0 ,1 ),1 ,1 ): print ("YES" ) print (0 ,1 ) print ("UR" )else : print ("NO" )