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))