1、小红的棋子移动
小红和朋友玩游戏,棋盘为\(n\times
m\) 的坐标轴。有一颗棋子在坐标\((1,1)\) 的位置,每次可以向上或者向右移动奇数单位,不能移动到棋盘外面,无法行动就输了,小红先手,请问小红能否必胜。
## 输入 一行一个整数\(t\) ,表示有组数据。
接下来\(t\) 行,每行两个整数\(n\) 和\(m\) ,表示棋盘大小。
\(1\le t\le 10^4\)
\(1 \le n,m \le 10^3\)
输出
对于每组数据,输出一行,如果小红必胜,输出Yes
,否则输出No
。
样例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 输入: 4 1 1 1 4 4 1 4 4 输出: No Yes Yes No 提示: 样例一,棋盘大小为1×1,小红无法行动,输了。 样例二,棋盘大小为1×4,小红第一次向右移动3个单位,小红获胜,朋友无法行动。 样例三,棋盘大小为4×1,小红第一次向上移动3个单位,小红获胜,朋友无法行动。
解答
由于每次移动都是移动奇数步,因此如果现在在坐标\((x,y)\) ,那么移动后的新坐标\((x',y')\) 必定满足:\(x+y\) 和\(x'+y'\) 的奇偶性并不同。因此,对于两个人所处的所有局面,\(x+y\) 的奇偶性都是相同的
此外,当棋子不能动时,它在位置\((n,m)\) 。因此,如果\(n+m\) 的奇偶性和\(1+1\) 相同,那么先手必败,否则先手必胜。
代码
1 2 3 4 T = int (input ()) for _ in range (T): n, m = map (int , input ().split()) print ("No" if (n + m) % 2 == 0 else "Yes" )
2、小红的交换排列
小红有一个长度为\(n\) 的排列,她可以选择两个位置,然后交换两个位置的数。
她想知道能否通过最多一次交换,使得存在一个连续子段,是长度为\(k\) 的排列。
排列是指一个长度为\(len\) 的整数数组,数组中包含\(1\) 到\(len\) 的每个数目每个数只出现一次。 ## 输入
一行两个整数\(n,k\) ,表示排列长度和连续子段长度。
一行\(n\) 个整数\(a_1,a_2,\dots,a_n\) ,表示排列。
输出
如果能够通过最多一次交换,存在一个连续子段是排列,输出YES
,并输出交换的位置:先输出一个整数\(x(0\le x\le 1)\) ,然后输出\(x\) ,每行两个整数\(u,v\) ,表示交换位置\(u,v\) 。
否则输出NO
。
样例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 输入: 5 3 1 2 3 4 5 输出: YES 0 提示: 子段[1,2,3]是长度为3的排列。 输入: 5 4 1 5 3 4 2 输出: YES 1 2 5 提示: 交换a2, a5后,[1,2,3,4,5]
解答
由于它这里只需要产生一个长度为\(k\) 的排列即可,因此我们可以将这个问题简化一下:将\(a_i\le
k\) 的所有数对应位置看成是一个比特\(1\) ,其余的所有位置看成是比特\(0\) 。由此我们得到了一个长度为\(n\) 的比特串\(s\) ,其中包含了\(k\) 个\(1\) ,问题是是否可以通过一次交换两个位置中的比特,从而使其中所有比特\(1\) 都相邻?
可以发现,无非只有\(4\) 种情况满足题目答案,分别如下:
1 2 3 4 ......000000011111111100000...... ......010000011111111100000...... ......000000011111111100010...... ......000000011111011110000......
其中,第\(1\) 种情况是已经符合答案的,不需要进行任何操作;第\(2\) 种和第\(3\) 种情况是对称的,有\(1\) 个\(1\) 比特游离在外,剩下的\(k-1\) 个比特相邻,这种方法是选择这\(k-1\) 个比特中,将左侧的\(0\) 或者是右侧的\(0\) 和游离在外的\(1\) 比特交换即可;第\(4\) 种情况则是\(k\) 个\(1\) 比特中间夹杂了\(1\) 个\(0\) 比特,只需要选择将它和最左侧或者是最右侧的\(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 def solve (): n, k = map (int , input ().split()) a = list (map (int , input ().split())) b = [i for i, x in enumerate (a) if x <= k] l, r = b[0 ], b[-1 ] if r - l == k - 1 : return 1 , [] elif r - l == k: loss = list (set (range (l, r + 1 )) - set (b))[0 ] other = b[0 ] return 1 , [(loss, other)] else : if b[-2 ] - b[0 ] == k - 2 : l, r, x = b[0 ], b[-2 ], b[-1 ] elif b[-1 ] - b[1 ] == k - 2 : l, r, x = b[1 ], b[-1 ], b[0 ] else : return 0 , [] if l == 0 : return 1 , [(r + 1 , x)] else : return 1 , [(l - 1 , x)] flag, sol = solve() print ("YES" if flag else "NO" )if flag: print (len (sol)) for x, y in sol: print (x + 1 , y + 1 )
3、小红的方法重载
请你编写一个系统用来管理方法的重载和调用。
共有以下2种操作:
创建一个方法:
输入的格式为:Type name(var1 a1, var2 a2......)"
,大括号和方法里内容
被省略。
调用一个方法:
输入的格式为:"name(var1, var2......)"
。
以上变量,vari
代表变量类型,ai
代表变量名,name
代表方法名Type
代表返回类型,均为由小写字母组成的字符串。
请你在每次操作后给出系统反馈。
创建方法时,若创建成功,则输出一个字符串"ok."
。否则输出一个字符串"method xxx is already defined."
调用方法时,若调用成功,则输出一个字符串"ok."
。若方法名不存在,则输出"cannot find symbol xxx."
。若方法名存在但方法内部的变量类型错误,则输出"method xxx cannot be applied to given types."
。
输入
第一行输入一个正整数\(q\) ,代表操作次数。
接下来的\(2\times q\) 行,每\(2\) 行代表一次操作。
第一行为一个正整数\(op\) ,代表操作类型。
第二行为一个字符串,代表一次操作。
\(1\le q\le 100\)
\(1\le op\le 2\)
操作的字符串长度不超过\(100\) ,且格式保证合法。
输出
输出\(q\) 行字符串,代表每次操作系统的反馈。
样例
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 输入: 7 1 int f(int x) 1 int g(int x,String s) 2 f() 1 void f(double x,double y) 2 f(double,double) 2 solve(int,String) 1 void f(int y) 输出: ok. ok. method f cannot be applied to given types. ok. ok. cannot find symbol solve. method f is already defined. 提示: 第一次操作,创建方法成功。 第二次操作,创建方法成功。 第三次操作,调用无参方法f(),虽然已经有了以名为的方法,但参 数类型不对,所以调用失败。 第四次操作,创建方法成功(本次重载了f方法) 第五次操作,调用方法f(double,double)成功。 第六次操作,调用方法solve(int,String),显然不存在该方法。 第七次操作,创建方法void f(int y),由于已经存在一个单int型参数的f方法,因此创建失败。
解答
可以直接按照题意进行模拟。将每一次定义方法和调用方法都解析成一个二元组:(方法名,参数类型列表),并且使用一个字典来存放对应方法名的参数列表。接下来就是直接模拟整个过程即可。
代码
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 mp = {} def parse_define (s ): s = s[s.find(' ' ) + 1 :] method_name = s[:s.find('(' )] t = s[s.find('(' ) + 1 :s.find(')' )].split(',' ) params_list = tuple (s[:s.find(' ' )] for s in t) return method_name, params_list def parse_invoke (s ): method_name = s[:s.find('(' )] params_list = tuple (s[s.find('(' ) + 1 :s.find(')' )].split(',' )) return method_name, params_list def solve_define (s ): method_name, params_list = parse_define(s) if method_name not in mp.keys(): mp[method_name] = set () if params_list in mp[method_name]: return "method {} is already defined." .format (method_name) else : mp[method_name].add(params_list) return "ok." def solve_invoke (s ): method_name, params_list = parse_invoke(s) if method_name not in mp.keys(): return "cannot find symbol solve." elif params_list not in mp[method_name]: return "method {} cannot be applied to given types." .format (method_name) else : return "ok." T = int (input ()) for _ in range (T): op, s = input (), input () print (solve_define(s) if op == '1' else solve_invoke(s))