{"trustable":false,"prependHtml":"\u003cstyle type\u003d\"text/css\"\u003e\n #problem-body \u003e pre {\n display: block;\n padding: 9.5px;\n margin: 0 0 10px;\n font-size: 13px;\n line-height: 1.42857143;\n word-break: break-all;\n word-wrap: break-word;\n color: #333;\n background: rgba(255, 255, 255, 0.5);\n border: 1px solid #ccc;\n border-radius: 6px;\n }\n\u003c/style\u003e\n","sections":[{"title":"","value":{"format":"MD","content":"\u003chtml\u003e\n \u003chead\u003e\u003c/head\u003e\n \u003cbody\u003e\n \u003cdiv id\u003d\"problem-body\"\u003e \n \u003cp\u003eIrving \u0026amp; Cohen Petroleum Corporation has decided to develop a new oil field in an area. A preliminary survey has been done and they created a detailed grid map of the area which indicates the reserve of oil.\u003c/p\u003e \n \u003cp\u003eThey are now planning to construct mining plants on several grid blocks according this map, but they decided not to place any two plants on adjacent positions to avoid spreading of fire in case of blaze. Two blocks are considered to be adjacent when they have a common edge. You are one of the programmers working for the company and your task is to write a program which calculates the maximum amount of oil they can mine, given the map of the reserve.\u003c/p\u003e \n \u003ch3\u003eInput\u003c/h3\u003e \n \u003cp\u003eThe first line of the input specifies N, the number of test cases. Then N test cases follow, each of which looks like the following:\u003c/p\u003e \n \u003cpre\u003eW H\nr\u003csub\u003e1,1\u003c/sub\u003e r\u003csub\u003e2,1\u003c/sub\u003e ... r\u003csub\u003eW,1\u003c/sub\u003e\n ... \nr\u003csub\u003e1,H\u003c/sub\u003e r\u003csub\u003e2,H\u003c/sub\u003e ... r\u003csub\u003eW,H\u003c/sub\u003e\u003c/pre\u003e \n \u003cp\u003eThe first line of a test case contains two integers W and H (1 ≤ W, H ≤ 20). They specifies the dimension of the area. The next H lines, each of which contains W integers, represent the map of the area. Each integer rx,y (0 ≤ rx,y \u0026lt; 10000) indicates the oil reserve at the grid block (x, y).\u003c/p\u003e \n \u003ch3\u003eOutput\u003c/h3\u003e \n \u003cp\u003eFor each test case, output the case number (starting from 1) and the maximum possible amount of mining in a line. Refer to the sample output section about the format.\u003c/p\u003e \n \u003ch3\u003eExample\u003c/h3\u003e \n \u003cpre\u003e\n\u003cb\u003eInput:\u003c/b\u003e\n2\n2 2\n2 3\n3 5\n3 2\n4 1 1\n2 1 4\n\n\u003cb\u003eOutput:\u003c/b\u003e\nCase 1: 7\nCase 2: 8\n\u003c/pre\u003e \n \u003c/div\u003e\n \u003c/body\u003e\n\u003c/html\u003e"}},{"title":"Test","value":{"format":"MD","content":"## 新生初赛题目、解题思路、参考代码一览\n### 1001. 无聊的日常\n\n#### Problem Description\n两位小朋友小A和小B无聊时玩了个游戏,在限定时间内说出一排数字,那边说出的数大就赢,你的工作是帮他们统计他们获胜的次数。\n\n#### Input\n第一行是一个T,代表游戏的次数T(T≤1000)。每组两个整数p,y(1≤p≤$10^{100}$,1≤y≤$10^{100}$),分别表示两位小朋友说出的数字。\n\n#### Output\n输出两个数,A和B获胜的次数。后面没有换行,仅此一题\n\n#### Sample Input\n2\n11 22\n22 11\n\n#### Sample Output\n1 1\n\n#### 解题思路\n- 签到题,但是要上天的出题人给的数据不对,造成了大量的WA。后来我点进去一看数据长度不对,放到python里len一下,数据竟然有70多位,才让大佬改成了$10^{100}$。\n- 很简单,比较两个数字的大小并统计次数就好了。但是数字非常大,你需要用一个字符串存储。\n- **字符串大数比较**,先比较长度,长度相同再从最高位向低位比较每一位的大小(直至不等)。\n- 应当注意,既然没说相等的情况,当然不应该把相等的情况也算进去。\n- 时间复杂度:O(N),常数为3以上。\n- 空间复杂度:O(N)\n\n#### 参考代码\n- ?:的语法是gnu c/c++独有,a ?: c等价于a ? (a) : c\n\n```c++\n#include \u003cstdio.h\u003e\n#include \u003cstring.h\u003e\n\nint main() {\n int T, resP \u003d 0, resY \u003d 0, temp;\n char p[99]\u003d{0}, y[99]\u003d{0};\n scanf(\"%d\", \u0026T);\n while (T--) {\n scanf(\"%s%s\", p, y);\n temp \u003d (int) strlen(p) - (int) strlen(y) ?: strcmp(p, y);\n if (temp \u003e 0) ++resP;\n else if (temp \u003c 0) ++resY;\n }\n printf(\"%d %d\", resP, resY);\n return 0;\n}\n```\n\u003cbr/\u003e\n### 1002. 写个编译器\n\n#### Problem Description\n写一个编译器,支持下列语言之一:\nC语言 https://en.wikipedia.org/wiki/C_(language)\n保证只有main函数\n只使用int char main printf关键字,除字符串外只有\" ( ) + - * \u003d , 数字 字母 { } ; 空格 换行 的出现,且没有undefined behavior\n保证没有判断、循环、递归\n如\nint main() {\nchar t;\nt \u003d 70;\nprintf (\"%cello\", t+\u003d2);\n}\nPython语言 https://en.wikipedia.org/wiki/Python_(programming_language)\n只使用print end关键字,除字符串外只有\" ( ) + - * \u003d , 数字 字母 空格 换行 的出现\n保证没有判断、循环、递归\n如\nprint (1, 4, end\u003d\"+11\u003d25\")\n\"输出14+11\u003d25,后面没有换行\"\nprint (1, 4, \"+11\u003d25\")\n\"输出14+11\u003d25,后面有换行\"\n\"没有print语句的表达式不会被输出\"\nJScript https://en.wikipedia.org/wiki/JScript\n只使用WScript.Echo WScript.StdOut.Write关键字,除字符串外只有\" ( ) + - * \u003d , 数字 字母 ; 空格 . 的出现(JScript的换行比较麻烦,暂且避开)\n保证没有判断、循环、递归,所有变量为数字或字符串\n如\nx\u003d3;WScript.Echo(x+6);WScript.Stdout.Write(\"1\\n2\");\nText语言 http://esolangs.org/wiki/Text\n除字符串外只有\" ( ) + - * 数字 字母 空格 换行 , { }\n保证没有循环、递归\n如\nOutput Character H\nLet t Be 3\nOutput String ell\nIf t-2 Positive {\nOutput Character With Ansii 111\n}\nIf t-4 Positive {\nOutput Character With Ansii 10\n}\nBrainFuck http://esolangs.org/wiki/Brainfuck\n保证只有\u003e \u003c + - . [ ]\n每个位置可以储存0-255的数字,超过将会绕回\n保证执行次数小于100 000\n\n#### Input\n依次输入几种语言的代码,两种语言之间以\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d(10个等号)分割。保证所有代码可以正常编译执行\n\n#### Output\n选择一种进行编译并输出运行结果。\n\n#### Sample Input\n```plain\nint main() {\n char t;\n t \u003d 70;\n printf (\"%cello\", t+\u003d2);\n}\n\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\nprint (1, 4, end\u003d\"+11\u003d25\")\n\"输出14+11\u003d25,后面没有换行\"\nprint (1, 4, \"+11\u003d25\")\n\"输出14+11\u003d25,后面有换行\"\n\"没有print语句的表达式不会被输出\"\n\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\nx\u003d3;WScript.Echo(x+6);WScript.Stdout.Write(\"1\\n2\");\n\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\nOutput Character H\nLet t Be 3\nOutput String ell\nIf t-2 Positive {\n Output Character With Ansii 111\n}\nIf t-4 Positive {\n Output Character With Ansii 10\n}\n\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\n+++++[\u003e++++++++\u003c-]\u003e.\n```\n\n#### Sample Output\n```plain\nHello\n```\n\n#### 解题思路\n- 又是大佬的神作,看看就好。\n- 向真的写了BrainFuck的巨巨们Orz一个。\n- 注意倒数第二种语言Text,输出就是源代码本身。\n- 时间复杂度:O(N),常数大概在1~3\n- 空间复杂度:O(N)\n\n#### 参考代码\n```c++\n#include \u003cstdio.h\u003e\n#include \u003cstring.h\u003e\n\nchar code[(int) (3e7)], *result \u003d code;\n\nint main() {\n fread(code, 1, (int) (3e7), stdin);\n for (int i \u003d 0; i \u003c 3; ++i)\n result \u003d strstr(result, \"\\n\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\\n\") + 12;\n *strstr(result, \"\\n\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\\n\") \u003d 0;\n printf(\"%s\", result);\n return 0;\n}\n```\n\u003cbr/\u003e\n### 1003. 手机密码\n\n#### Problem Description\n某天CZJ在玩辣鸡游戏,玩着玩着发现手机被hack了,重启之后发现界面上出现了一个数字和一个密码框。\nCZJ试了半天发现,当输入的正整数满足以下条件时,界面上不会弹出可恶的错误:\n1. 它的二进制形式中1的数量和显示数字的(二进制中1数量)相同;\n2. 十进制大于显示的数字;\n3. 在所有可行答案中最小。\n\n可悲的是又跳出一个数字。CZJ算了几个之后觉得好麻烦,你可以帮他算一下吗?\n\n#### Input\n第一行是一个T,代表数据的组数T(T≤100001)。接下来是T行,每行有一个数字N,表示显示的数字(1≤n≤1000000000)。\n\n#### Output\n针对每一个数字输出对应密码。\n\n#### Sample Input\n2\n1\n5\n\n#### Sample Output\n2\n6\n\n#### Hint\n1的二进制表达为1,2的二进制表达为10,5的是101,6的是110\n\n#### 解题思路\n- 首先只考虑第一个条件。统计数字N的二进制表示中,“1”的数量C。然后输出一个数X,使得X的二进制表示是由C个连续的“1”构成。\n- 再考虑第二个条件,要求输出的X要比N大。那就**从右边找极值**,从右到左扫描N的二进制,先扫过一段连续的“0”,再扫过一段连续的“1”,之后再第一次扫描到“0”时停止。如N\u003d92(01**01** 1100)。把这一位0置为1,下一位1置为0(为了保证“1”的个数不变),像这样:X\u003d108(01**10** 1100)。这样输出X的确要比原数N大。\n- 最后考虑第三个条件,在所有可行方案中最小。我们再次考察X\u003d108(01*10* **1100**),由于X\u003d108具有N\u003d88所没有的更高位的“1”,所以X一定比N大,而不论后面低位的数字如何变化。于是**重排**X\u003d99(01*10* **0011**),也就是将比变换位低位的1全部移到右边去。\n- 时间复杂度:O(d)\u003dO(logN)\n- 空间复杂度:O(1)\n\n#### 参考代码1\n- __builtin_ctz函数是gnu c/c++独有,用于计算从右起第一个“1”之后的“0”的个数,参数为0时是ub;\n- 也可以用__builtin_ffs函数找到从右起第一个“1”的位置;\n- 然而这些函数看看就好,记得可以用,还是推荐自己算。\n\n```c++\n#include \u003cstdio.h\u003e\n\nint main() {\n int T, N, a, b, t;\n scanf(\"%d\", \u0026T);\n while (T--) {\n scanf(\"%d\", \u0026N);\n t \u003d a \u003d N \u0026 -N;\n do a \u003c\u003c\u003d 1; while (a \u0026 N);\n b \u003d (N \u0026 (~(-a))) \u003e\u003e (__builtin_ctz(t) + 1);\n N \u003d N \u0026 -a ^ a ^ b;\n printf(\"%d\\n\", N);\n }\n return 0;\n}\n```\n#### 参考代码2\n```c++\n#include \u003cstdio.h\u003e\n\nint main() {\n int T, N, a, b;\n scanf(\"%d\", \u0026T);\n while (T--) {\n scanf(\"%d\", \u0026N);\n a \u003d 0, b \u003d 0;\n while (!(N \u0026 1)) N \u003e\u003e\u003d 1, ++a;\n while (N \u0026 1) N \u003e\u003e\u003d 1, ++b;\n printf(\"%d\\n\", ((N | 1) \u003c\u003c (a + b)) \u0026 (~((1 \u003c\u003c (a + b)) - 1)) | ((1 \u003c\u003c (b - 1)) - 1));\n }\n return 0;\n}\n```\n\u003cbr/\u003e\n### 1004. Zyj大逃亡\n\n#### Problem Description\nZyj打比赛时又没做出题来,还写崩了一道题,他的队友们和SCNU的大佬们都跑来追杀他啦!Zyj在逃亡过程中和大佬们一起穿越到了LOL世界中。大佬们启动了“疾走”技能,很快就把Zyj围堵到了一个包围圈中。\nZyj拥有一个被动技能,当不向敌人走动时能获得飞一般的速度,从而逃出包围圈。已知包围圈的半径为$R$,可以设Zyj所在位置为原点O,大佬们都恰好站在圆上一点,并知道每位大佬的坐标位置为$P_i(x_i, y_i)$。显然每位大佬之间都隔着一段圆弧,Zyj可以且仅可以从长度$L \\geqslant \\frac12 R$的圆弧的中点逃出以保证他的被动技能生效。若不存在这样的圆弧(即长度都太短)则Zyj无路可逃。\n注意,如果Zyj的可选最长圆弧不唯一,即使长度足够,也认为Zyj无论走哪个方向都不背向敌人,Zyj还是无路可逃。\n\n#### Input\n第一行只有一个正整数$T$($T \\leqslant 1000$),代表了$T$个情形。\n接下来有$T$组输入,每组输入中包含两个正整数$N$($N\u003e3$)和$R$($0\u003cR\u003c1000$),分别代表包围圈的半径和追杀Zyj的大佬数量。接下来$N$行每行有$2$个数字,分别代表$N$个大佬的坐标$(x_i, y_i)$,保证所有的$x_i^2+y_i^2\u003dR^2$成立,提供数据的精度保证7位有效小数(舍入后)。保证数据读得完。\n\n#### Output\n对于每个Zyj逃亡的情形,如果Zyj能逃出来,则输出Zyj可逃离的最长圆弧的中点的坐标(保证答案唯一,且保留4位小数);如果Zyj无路可逃,请输出\"Zyj has been slain\"(不包括双引号)。\n\n#### Sample Input\n2\n4 25\n0 25\n-25 0\n-0 -25\n25 -0\n4 25\n0 25\n0 -25\n20 15\n20 -15\n\n#### Sample Output\nZyj has been slain\n-25.0000 0.0000\n\n#### 解题思路\n- 我出的题。题目有修改,“如果Zyj的可选最长圆弧不唯一”原本的描述是“如果Zyj能选择的所有圆弧都等长”,但是多事的oyk说看不懂,结果改了描述后好像变难了。我的代码仍然是“所有等长”的版本,如果要判“最长不唯一”,要另开数组标记一下浮点数。\n- 如果用笛卡尔坐标系,不是不能做,挺难的。考虑**极坐标系**,由于坐标都在圆上,长度均等于R。每个大佬的直角坐标对应极坐标角度angle,对angle进行排序,两两相减得到每段圆弧所对圆心角theta,遍历一遍这个theta,最后有答案就除以2再转直角坐标。\n- 注意由于是个**圆**,还要算上**第一个和最后一个**坐标之间的圆弧。\n- 正确姿势做法:**极角排序**。\n- 奇怪的错误点:\n 1. 完全不会测试浮点数,判断相等时有精度问题;\n 2. 完全不会比较浮点数,判断大小时比较错误。\n- 时间复杂度:O(NlogN)\n\n#### 参考代码\n- C语言在stdlib.h里有个qsort排序函数\n- C++在algorithm中(STL)有个std::sort排序函数\n- 不要干手写冒泡排序这种奇怪的事情,手写快排也不要\n- 浮点数由于精度误差,不能直接比较相等,要设置一个较小的允许误差,小于这个误差可认为等于0\n\n```c++\n#include \u003cstdio.h\u003e\n#include \u003cstring.h\u003e\n#include \u003cmath.h\u003e\n#include \u003cstdlib.h\u003e\n\n//做自己出的题WA了是一种怎样的体验?Zyj的回答,获得0个赞同。\nconst double PI \u003d acos(-1.);\n\nint angleCount;\ndouble angleArray[10000];\n\nvoid init() {\n angleCount \u003d 0;\n memset(angleArray, 0x0, sizeof(angleArray));\n}\n\nint N, R;\n\nvoid read() {\n double x, y;\n scanf(\"%d%d\", \u0026N, \u0026R);\n for (int i \u003d 0; i \u003c N; ++i) {\n scanf(\"%lf%lf\", \u0026x, \u0026y);\n angleArray[angleCount++] \u003d atan2(y, x);\n }\n}\n\nint fcmp(double a, double b) {\n /*if (fabs(a - b) \u003c\u003d 1e-7)*/\n if (fabs(a - b) / fabs(a) \u003c\u003d 1e-7 ||\n fabs(a - b) / fabs(b) \u003c\u003d 1e-7)\n return 0;\n if (a \u003c b) return -1;\n /*if (a \u003e b)*/ return 1;\n}\n\nint compareDouble(const void *a, const void *b) {\n return fcmp(*(double *) a, *(double *) b);\n}\n\nvoid work() {\n qsort(angleArray, (size_t) angleCount, sizeof(double), compareDouble);\n angleArray[angleCount++] \u003d angleArray[0] + 2. * PI;\n\n int isNotSame \u003d 0;\n int rangeUpperIdx \u003d 1;\n double maxRange \u003d angleArray[rangeUpperIdx] - angleArray[rangeUpperIdx - 1];\n for (int i \u003d 2; i \u003c angleCount; ++i) {\n double temp \u003d angleArray[i] - angleArray[i - 1];\n int cmpJudge \u003d fcmp(temp, maxRange);\n if (cmpJudge) ++isNotSame;\n if (cmpJudge \u003e 0) {\n maxRange \u003d temp;\n rangeUpperIdx \u003d i;\n }\n }\n if (isNotSame \u0026\u0026 fcmp(maxRange, 0.5) \u003e 0) {\n double theta \u003d (angleArray[rangeUpperIdx] + angleArray[rangeUpperIdx - 1]) / 2.;\n printf(\"%.4f %.4f\\n\", R * cos(theta), R * sin(theta));\n } else {\n printf(\"Zyj has been slain\\n\");\n }\n}\n\nint main() {\n int T;\n scanf(\"%d\", \u0026T);\n while (T--) {\n init();\n read();\n work();\n }\n return 0;\n}\n```\n\u003cbr/\u003e\n### 1005. Czj数数\n\n#### Problem Description\n自从Czj上了初中,已经不再满足于从1数到100了,他打算来个高难度的挑战。\n设a1\u003d1,a2\u003d11,有数列ai,任意1\u003ci≤n,元素ai−1与其自身的最后一位数字组成了新的数字X(如233将会变成2333),而ai是X的最大质因子。由于Czj很懒,数到2333就觉得无聊而跑去写gc了。现在请你帮他完成这未竟的事业。\n\n#### Input\n第一行是一个正整数T(T\u003c100),代表接下来有T次询问。\n接下来的T行,每一行输入一个正整数i(1≤i≤104)。\n\n#### Output\n对于每次询问,你应该求出数组中的第i个元素ai,并以\"Case #t: ai\"的格式单独输出一行,不包括双引号。其中#t代表询问的编号。\n\n#### Sample Input\n3\n5\n6\n7\n\n#### Sample Output\nCase #1: 23\nCase #2: 233\nCase #3: 2333\n\n#### 解题思路\n- 还是本菜鸡出的题。\n- **遇事不决打个表**。如果你打了表,你就会发现生活的美好——这里面原来是有**循环节**的。从第5个数开始,到第30个数,是一个循环节。\n- 一般这种一眼看过去是递推,又没找到公式,干脆想都不要想直接打表出来,找有没有循环节,没有循环节再找规律。\n- 怎么找一个数的最大质因子呢?不需要素数筛,试除法就行。当然你开心的话,可以上Eratothenes筛或欧拉筛打素数表。试除法打素数表是会超时的。当然这里用到的素数还不大于100。\n- 时间复杂度:O(1)或O($M\\sqrt{N}$)或O($M\\log \\log N$),M\u003d??\n\n#### 求最大质因子\n```c++\n/**\n * find out the largest prime factor of given num.\n */\nint largestFactorOf(int num) {\n int iterateNumber \u003d num;\n int q \u003d (int) sqrt(num) + 1;\n int iterateFactor \u003d 2;\n while (iterateFactor \u003c\u003d q) {\n while (iterateNumber % iterateFactor \u003d\u003d 0)\n iterateNumber /\u003d iterateFactor;\n if (iterateNumber \u003d\u003d 1)\n break;\n ++iterateFactor;\n }\n return iterateNumber \u003d\u003d 1 ? iterateFactor : iterateNumber;\n}\n```\n\n#### 参考代码\n```c++\n#include \u003cstdio.h\u003e\n\n/**\n * http://oeis.org/A195201\n * Description: for a(1) \u003d 1, a(n) is the largest prime factor of\n * the number which is made up from a(n-1) and its last digit.\n * Input: T, and T lines of any n.\n * Output: a(n) for every n.\n * */\n\nconst int fixedSection[4] \u003d {\n 1, 11, 37, 29\n};\nconst int cycleSection[26] \u003d {\n 23, 233, 2333, 23333, 661, 601, 6011, 6679,\n 997, 907, 313, 241, 2411, 47, 53, 41, 137,\n 17, 59, 599, 857, 953, 9533, 13619, 19457, 821\n};\nint T, n;\n\nvoid read() {\n scanf(\"%d\", \u0026n);\n}\n\nvoid work(int caseCount) {\n printf(\"Case #%d: %d\\n\", caseCount, n \u003c\u003d 4 ? fixedSection[n - 1] : cycleSection[(n - 5) % 26]);\n}\n\nint main() {\n scanf(\"%d\", \u0026T);\n for (int i \u003d 1; i \u003c\u003d T; ++i) {\n read();\n work(i);\n }\n return 0;\n}\n```\n\u003cbr/\u003e\n### 1006. 飞来飞去的Zyj\n\n#### Problem Description\nZyj在接电路板。他给出了要连接的线的列表,并按顺序进行连接。但是他不绕线,如果两个点连成的线段不与任何画线相交,就在上面把线画出来,否则就直接上飞线(即这根线不画在电路板上,而是在空中连接)。问,Zyj一共飞了几条线?\n注意,如果其中一条线经过另一条线的端点,视为相交;但如果两条线在端点上相接,视为不相交。部分重叠视为相交,除非在端点上相接\n\n#### Input\n第一行T为数据组数(小于100)\n每组数据的第一行n为连线数量(小于100),后面紧跟着n行(x1,y1)-(x2,y2)表示端点坐标。坐标值的绝对值小于100.\n\n#### Output\n对每组数据,输出Case #d: q,其中d为数据编号,q为飞线数量。\n\n#### Sample Input\n2\n7\n(1,2)-(4,2)\n(4,2)-(4,1)\n(4,1)-(2,1)\n(2,1)-(2,4)\n(2,4)-(3,4)\n(3,4)-(3,3)\n(1,3)-(3,3)\n4\n(1,1)-(7,1)\n(2,1)-(2,2)\n(3,1)-(4,1)\n(6,1)-(7,1)\n\n#### Sample Output\nCase #1: 1\nCase #2: 2\n\n样例解释:\n\n\u003cpre style\u003d\"line-height:normal;\"\u003e\n4 ┎┐ \u003cbr\u003e\n3 ─╂┘ \u003cbr\u003e\n2 ─╂─┐ \u003cbr\u003e\n1 ┗─┘ \u003cbr\u003e\n 1234\u003cbr\u003e\n \u003cbr\u003e\n2 ┃ \u003cbr\u003e\n1 ─┸──────── \u003cbr\u003e\n ━━ ──(这行和上一行是叠在一起的)\u003cbr\u003e\n 1234567 \u003cbr\u003e\n其中粗线表示飞线\u003cbr\u003e\n\u003c/pre\u003e\n\n#### 解题思路\n- 讲真,这题我也不会做。反正又是大佬的神作。\n- 后来搜了下,**线段判交**是有技巧的,常用的是向量积;也可以直接解析几何解方程。这里用了随便一搜能搜出来的快速排斥+跨立试验。\n- 需要注意的是**1.按顺序连接;2.重叠相交;3.端点连接强制不相交;4.应当标记飞过的线。**\n- 时间复杂度:O($N^2$)\n\n#### 参考代码(因为我不会做,直接用C++了)\n```c++\n#include \u003cstdio.h\u003e\n#include \u003cstring.h\u003e\n#include \u003calgorithm\u003e\n\nusing std::max;\nusing std::min;\n\ninline int feq(const double \u0026a, const double \u0026b) {\n return fabs(a - b) \u003c 1e-7;\n}\n\ninline int fneq(const double \u0026a, const double \u0026b) {\n return !feq(a, b);\n}\n\ninline int fgeq(const double \u0026a, const double \u0026b) {\n return feq(a, b) || a \u003e b;\n}\n\nstruct Point {\n double x, y;\n\n Point() {}\n\n Point(double x, double y) : x(x), y(y) {}\n\n int operator!\u003d(const Point \u0026p) const {\n return fneq(x, p.x) || fneq(y, p.y);\n }\n};\n\nstruct Line {\n double x, y;\n\n Line() {}\n\n Line(const Point \u0026P0, const Point \u0026P1) : x(P1.x - P0.x), y(P1.y - P0.y) {}\n\n double operator^(const Line \u0026l) const {\n return x * l.y - y * l.x;\n }\n};\n\ntypedef Point Segment[2];\n\ninline int quickReject(Segment \u0026A, Segment \u0026B) {\n return max(A[0].x, A[1].x) \u003e\u003d min(B[0].x, B[1].x) \u0026\u0026\n max(A[0].y, A[1].y) \u003e\u003d min(B[0].y, B[1].y) \u0026\u0026\n max(B[0].x, B[1].x) \u003e\u003d min(A[0].x, A[1].x) \u0026\u0026\n max(B[0].y, B[1].y) \u003e\u003d min(A[0].y, A[1].y);\n}\n\ninline int quickCross(Segment \u0026A, Segment \u0026B) {\n return (Line(B[0], A[0]) ^ Line(B[0], B[1])) * (Line(B[0], B[1]) ^ Line(B[0], A[1])) \u003e\u003d 0 \u0026\u0026\n (Line(A[0], B[0]) ^ Line(A[0], A[1])) * (Line(A[0], A[1]) ^ Line(A[0], B[1])) \u003e\u003d 0;\n}\n\nint flown[101];\nSegment seg[101];\n\nint main() {\n int T, N;\n scanf(\"%d\", \u0026T);\n for (int cse \u003d 1; cse \u003c\u003d T; ++cse) {\n int res \u003d 0;\n memset(flown, 0x0, sizeof(flown));\n scanf(\"%d%*c\", \u0026N);\n for (int i \u003d 0; i \u003c N; ++i) {\n scanf(\"%*c%lf%*c%lf%*c%*c%*c%lf%*c%lf%*c%*c\", \u0026seg[i][0].x, \u0026seg[i][0].y, \u0026seg[i][1].x, \u0026seg[i][1].y);\n for (int j \u003d 0; j \u003c i; ++j)\n if (quickReject(seg[j], seg[i]) \u0026\u0026 quickCross(seg[j], seg[i]) \u0026\u0026\n seg[j][0] !\u003d seg[i][0] \u0026\u0026 seg[j][0] !\u003d seg[i][1] \u0026\u0026\n seg[j][1] !\u003d seg[i][0] \u0026\u0026 seg[j][1] !\u003d seg[i][1] \u0026\u0026 !flown[j]) {\n flown[i] \u003d 1;\n ++res;\n break;\n }\n }\n printf(\"Case #%d: %d\\n\", cse, res);\n }\n return 0;\n}\n```\n\u003cbr/\u003e\n### 1007. 灌水\n\n#### Problem Description\nCZJ和L2M在车上闲着没事拿了个水杯灌水,规定杯子的体积P和每次可以倒进杯子的水的最大体积Y,两个人轮流向杯子灌整数体积的水,最后灌满杯子的人获胜。\nCZJ看起来很想赢的样子,L2M宽宏大量的给了先手。但是CZJ这么菜,你能教下CZJ起手要灌多少才能必胜吗?\n\n#### Input\n第一行是一个T,代表数据的组数T(T≤20000)。每组两个整数p,y(1≤p≤10000000,1≤y≤10000000)。\n\n#### Output\n对于每组数据输出CZJ起手灌水的数量,如果CZJ赢不了,打出GG。\n\n#### Sample Input\n2\n3 1\n2 1\n\n#### Sample Output\n1\nGG\n\n#### 解题思路\n- 首先这是一个入门级博弈问题。不知道博弈的也没关系,如果你有耐心,在纸上演算一下6以内的情况,就会发现规律。\n- 这个问题是**巴什博奕先手赢**。我们总考虑P\u003eV,否则先手必胜的。\n- 我们先找一个**先手必败态:P\u003dY+1**。无论先手怎么倒水,总不能倒满,而后手总能把杯子倒满,所以这种情况先手必败。\n- 在其他情况下,能不能想办法把这个**必败态转移给对手**呢?考虑只有两局,第一局先手先倒M的水,后手和第二局先手总共倒N\u003dP-M的水,并且要保证第二局先手胜。\n- 我们发现这相当于只有一局——不管先手倒多少体积为M的水,就当水杯体积是P-M好了,这样**原本的后手等价成为了新的先手**。如果剩下的体积刚好N\u003dY+1,那么原本的后手就陷入了**先手必败困局**。\n- 如果除去一开始倒的M水,每一局都总共倒Y+1的水呢?因为Y\u003cY+1\u003c2Y,新的先手永远最多只能倒1\u003c\u003dZ\u003c\u003dY的水,而新的后手**总能控制局面的变化**,即他能倒Y+1-Z\u003c\u003dY的水。控制每次两人总共倒Y+1的水,就赢了。\n- 为什么一定是Y+1,不能是+2、+3吗?因为再多的话,先手就不是必败了,先手总能取一个较小值使得后面剩下Y+1。\n- 所以一开始要抢先倒P%(Y+1)的水,后面总共倒的水体积是(Y+1)的倍数。\n\n#### 参考代码\n```c++\n#include \u003cstdio.h\u003e\n\nint main() {\n int p, y;\n scanf(\"%d\", \u0026p);\n while (~scanf(\"%d%d\", \u0026p, \u0026y))\n (p %\u003d (y + 1)) ? printf(\"%d\\n\",p) : puts(\"GG\");\n return 0;\n}\n```\n\u003cbr/\u003e\n### 1008. 和\n\n#### Problem Description\n输入几个数字,求和。\n\n#### Input\n每行一个样例,由正整数组成,空格分开\n\n#### Output\n对每个样例,输出和。保证结果小于$10^9$\n\n#### Sample Input\n1 1\n1 2\n\n#### Sample Output\n2\n3\n\n#### 解题思路\n- 签到题,注意题面的**“几个数字”**。\n- 用EOF判输入结束。可以用一个小char判断换行。\n\n#### 参考代码\n```c++\n#include \u003cstdio.h\u003e\n\nint main() {\n int res, a, c;\n while (~scanf(\"%d\", \u0026res)) {\n while (scanf(\"%c\", \u0026c), c !\u003d \u0027\\n\u0027) {\n scanf(\"%d\", \u0026a);\n res +\u003d a;\n }\n printf(\"%d\\n\", res);\n }\n return 0;\n}\n```\n\u003cbr/\u003e\n### 1009. 开饭\n\n#### Problem Description\nCZJ的舍友请CZJ吃饭,作为舍友CZJ是不会放过吃穷舍友的机会,但自己身体又不好,不能吃太多也不能吃太少。假设每样食物都有一个饱腹度和价值,请你帮他算下刚好吃饱的情况下最多可以吃他舍友多少钱。\n\n#### Input\n第一行是一个T,代表数据的组数T(T≤100001)。每组两个整数p,y(1≤p≤1000,1≤y≤100),分别表示食物的数量和CZJ的饱腹度。\n然后p个数$Q_{p_i}$表示第$p_i$个食物的价值,之后p个数$M_{p_i}$表示吃第$p_i$个食物得到的饱腹度。(1≤$Q_{p_i}$≤10000,1≤$M_{p_i}$≤1000)。\n\n#### Output\n对于每一个样例输出CZJ能吃下的最大价值。\n\n#### Sample Input\n1\n5 100\n11 6 7 5 6\n40 50 60 20 30\n\n#### Sample Output\n18\n\n#### 解题思路\n- **0-1背包问题**求最大值。入门级dp。\n- 对于这题有很多人过没有意外。只要你搜一下什么叫“动态规划”或者“dp”,把0-1背包的递推往这一套,就A了。\n- 推荐学习资料:“背包九讲”、“动态规划32讲”。\n\n#### 参考代码\n```c++\n#include \u003cstdio.h\u003e\n#include \u003cstring.h\u003e\n\n#define MAXN 1010\nint C[MAXN], W[MAXN], dp[MAXN];\n\nvoid init() {\n memset(C, 0x0, sizeof(C));\n memset(W, 0x0, sizeof(W));\n // dp数组初始值要足够小。这里一个int是0x80808080\n memset(dp, 0x80, sizeof(dp));\n dp[0] \u003d 0;\n}\n\nvoid getMax(int \u0026a, int b) {\n if (a \u003c b) a \u003d b;\n}\n\nint N, V;\n\nvoid read() {\n scanf(\"%d%d\", \u0026N, \u0026V);\n for (int i \u003d 0; i \u003c N; ++i) scanf(\"%d\", W + i);\n for (int i \u003d 0; i \u003c N; ++i) scanf(\"%d\", C + i);\n}\n\nvoid work() {\n for (int i \u003d 0; i \u003c N; ++i)\n for (int v \u003d V; v \u003e\u003d C[i]; --v)\n getMax(dp[v], dp[v - C[i]] + W[i]);\n printf(\"%d\\n\", dp[V]);\n}\n\nint main() {\n int T;\n scanf(\"%d\", \u0026T);\n while (T--) {\n init();\n read();\n work();\n }\n return 0;\n}\n```\n\u003cbr/\u003e\n### 1010. Zyj消极比赛\n\n#### Problem Description\nACM比赛剩下最后10分钟,其他人都已经收拾好东西准备走人,Zyj才从睡梦中醒来。Zyj可以看到所有其他人的过题情况,他希望得到的名次在a到b之间,问有几种可选择的方案?(假设其他人的提交时间即使加上罚时也早于Zyj的提交,毕竟剩下10分钟了都)\n\n#### Input\n第一行为T(0\u003cT\u003c100),代表有T组数据。\n每组数据中第一行为两个数字m n a b,由空格隔开,代表这次比赛有m道题(由于字母数量的限制,0\u003cm\u003c27),n个其他人,Zyj希望得到的名次x满足a\u003cx\u003cb (-1\u003cn,a,b\u003c1000)\n下面n行为每个人每道题的通过情况,1为已通过,0为未通过\n\n#### Output\n对每个样例,输出Case #k: ans,其中k为样例编号,ans为方案数量。\n\n#### Sample Input\n2\n26 1 0 2\n1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0\n26 1 0 2\n0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0\n(Case #1是25个1 1个0,#2是1个0 24个1 1个0)\n\n#### Sample Output\nCase #1: 1\nCase #2: 27\n样例解释:\nCase #1中Zyj必须AK(全部题都做出来)才可以得到大于0小于2的名次,即第1名。不要怕他做不完,那可是Zyj\nCase #2中Zyj可以AK,也可以任意选一道不做\n\nACM排名规则见http://scnuacm2015.sinaapp.com/php/presentation.php\n\n#### 解题思路\n- 对于这种题我只能无语。\n- 这里有个**隐含条件**,因为Zyj是最后做题,罚时爆炸,所以无论他做多少题,都是**同题数的最后一名**。\n- 然后累加出每个人过题的数量,进而**统计过0≤x≤m题的人数**,从最高名次到最低名根据Zyj想要的名次去**求组合数**就好。\n- 一些错误点:\n 1. 没有处理好边界,对于不可能存在/达到的排名,计算结果不为0;\n 2. 同题数计算排名时没有考虑zyj是最后做题;\n 3. 没有加上当有人过0题时,zyj拿最后一名也可以过0题的1种情况;\n 4. 并列排名不顺延,比如1题的最后一名可能是x,那么0题的并列排名是x+1而不是n;\n 5. 有没看懂题的,把过题总数直接作为排名(也是没考虑过题时间会影响排名);\n 6. 还有一些奇怪的错误..不会算组合数or阶乘..有的没考虑除0..有的没考虑计算过程不整除..有的..我也不知道。\n- 时间复杂度:$O(m*m)$或$O(m+m*m)$(公式法预处理)或$O(m+m)$(预处理阶乘及其逆元)\n\n#### 参考代码1\n```c++\n#include \u003cstdio.h\u003e\n#include \u003cstring.h\u003e\n\n/*\n * count[k] 记录了过了k题的人数\n */\nint m, n, a, b;\nint count[27];\n\nvoid init() {\n memset(count, 0x0, sizeof(count));\n}\n\nvoid read() {\n scanf(\"%d%d%d%d\", \u0026m, \u0026n, \u0026a, \u0026b);\n for (int i \u003d 0; i \u003c n; ++i) {\n int acc \u003d 0, temp;\n for (int j \u003d 0; j \u003c m; ++j) {\n scanf(\"%d\", \u0026temp);\n acc +\u003d temp;\n }\n // 实际上count[0]没有利用价值\n ++count[acc];\n }\n}\n\n// 求组合数 - 魔幻除法(可以想想为什么能整除)\nint C(int n, int x) {\n int res \u003d 1;\n if (n - x \u003e x) x \u003d n - x;\n n -\u003d x;\n for (int i \u003d 1; i \u003c\u003d n; i++)\n res \u003d res * (x + i) / i;\n return res;\n}\n\nint work() {\n int res \u003d 0, rank \u003d 1;\n for (int i \u003d m; i \u003e 0; --i) {\n // zyj 做i题能拿的名次\n rank +\u003d count[i];\n if (a \u003c rank \u0026\u0026 rank \u003c b)\n res +\u003d C(m, i);\n }\n // 就算做0题,zyj也是拿同做1题一样的排名\n if (a \u003c rank \u0026\u0026 rank \u003c b)\n res +\u003d 1;\n return res;\n}\n\nint main() {\n int T;\n scanf(\"%d\", \u0026T);\n for (int cse \u003d 1; cse \u003c\u003d T; ++cse) {\n init();\n read();\n printf(\"Case #%d: %d\\n\", cse, work());\n }\n return 0;\n}\n```\n\n#### 参考代码2\n```c++\n#include \u003cstdio.h\u003e\n#include \u003cstring.h\u003e\n\n/*\n * count[k] 记录了过了k题的人数\n */\nint m, n, a, b;\nint count[27];\n\nvoid init() {\n memset(count, 0x0, sizeof(count));\n}\n\nvoid read() {\n scanf(\"%d%d%d%d\", \u0026m, \u0026n, \u0026a, \u0026b);\n for (int i \u003d 0; i \u003c n; ++i) {\n int acc \u003d 0, temp;\n for (int j \u003d 0; j \u003c m; ++j) {\n scanf(\"%d\", \u0026temp);\n acc +\u003d temp;\n }\n // 实际上count[0]没有利用价值\n ++count[acc];\n }\n}\n\n// 求组合数 - 公式预处理法\nint C[27][27];\nconst int MOD \u003d 1000000007;\nvoid pre() {\n C[0][0] \u003d C[1][0] \u003d C[1][1] \u003d 1;\n // 公式 C(n,x) \u003d C(n-1,x-1) + C(n-1,x)\n for(int n \u003d 2; n \u003c\u003d 26; n++) {\n C[n][0] \u003d C[n][n] \u003d 1;\n for(int x \u003d 1; x \u003c n; x++)\n C[n][x] \u003d (C[n-1][x-1] + C[n-1][x]) % MOD;\n }\n}\n\nint work() {\n int res \u003d 0, rank \u003d 1;\n for (int i \u003d m; i \u003e 0; --i) {\n // zyj 做i题能拿的名次\n rank +\u003d count[i];\n if (a \u003c rank \u0026\u0026 rank \u003c b)\n res +\u003d C[m][i];\n }\n // 就算做0题,zyj也是拿同做1题一样的排名\n if (a \u003c rank \u0026\u0026 rank \u003c b)\n res +\u003d 1;\n return res;\n}\n\nint main() {\n pre();\n int T;\n scanf(\"%d\", \u0026T);\n for (int cse \u003d 1; cse \u003c\u003d T; ++cse) {\n init();\n read();\n printf(\"Case #%d: %d\\n\", cse, work());\n }\n return 0;\n}\n```\n\u003cbr/\u003e\n### 1011. Oyk剪纸\n\n#### Problem Description\nOyk要把一张矩形纸剪成N张一样的矩形不留剩余,使用的方法为\n1.从一个方向剪若干(可能为0)刀\n2.从与其垂直的方向再剪若干刀\n那么他至少要剪几刀?\n\n#### Input\n多(少于1000)组样例,每行一个数字N(大于0小于1亿)。\n\n#### Output\n对每个样例,输出一行结果。\n\n#### Sample Input\n4\n5\n60\n\n#### Sample Output\n2\n4\n14\n解释:\n\n\u003cpre style\u003d\"line-height:normal;font-family:Helvetica,Arial,Monospace,sans-serif;\"\u003e\n┌┬┐┌┬┬┬┬┐ \u003cbr\u003e\n├┼┤└┴┴┴┴┘ \u003cbr\u003e\n└┴┘ \u003cbr\u003e\n\u003c/pre\u003e\n\n#### 解题思路\n- 首先剪的方向只能是与纸边平行或垂直。斜着剪会产生剩余,而且也产生负收益(浪费了剪的次数)。\n- 于是问题分解成了$N\u003dx * \\frac{N}{x}$,$r\u003d(x-1)+(\\frac{N}{x}-1)$,要让$r$尽可能小。不记得什么不等式了。\n- 直接任性求导,$r\u0027\u003d1-\\frac{N}{x^2}\u003d0$,**在$x\u003d\\sqrt{N}$处$r$取得最小值。**但注意x要是整数(不可能剪半刀)。\n- 时间复杂度:O($\\sqrt{N}$),**最坏情况由N是素数产生**。\n\n#### 参考代码\n```c++\n#include \u003cstdio.h\u003e\n#include \u003cmath.h\u003e\n\nint main() {\n int N, q;\n while (~scanf(\"%d\", \u0026N)) {\n q \u003d (int) sqrt(N);\n for (; q \u003e 1; --q)\n if (N % q \u003d\u003d 0) break;\n printf(\"%d\\n\", q + N / q - 2);\n }\n return 0;\n}\n```\n\u003cbr/\u003e\u003cbr/\u003e\n## 出题及解题总结\n\n### 我出的两题\n- 1004、1005都是我出的题。设计是一简单一难的。\n- 1004极角排序我想对新生来说还是挺难想到并做出的,事实上我出数据都快出成傻逼了;\n- 1005循环节打表可能我太高估新生水平了(?),因为我并没有出1e9的数据去卡素数表,而且数据范围设置非常小,试除法也不至于TLE,基本上是随意过的。理想情况是再不济一堆WA或TLE吧,结果伤心的发现没人做(逃)。\n\n### 整体情况总结\n1. 首先看统计数据,1001的WA接近500,这里Czj应该背锅,题面数据范围与实际不符。还有一个不输出回车的坑爹设定,强行卡题意,WA得惨不忍睹,严重打击了部分同学信心。\n2. 统计数据还有第二个明显峰度在1003的OLE上。因为我看不到提交代码,没法分析。\n - 有可能是hdoj的OLE是这么判的:输出超过标准答案即判OLE。如果是这样,很多OLE应当划到WA里面。\n - 但是也有反映将C++的输出换成C语言的输出即可通过。这应当是hdoj的锅了。\n3. 还有两个WA小高峰位于1003、1008。\n - 1003的确是很多同学根本没接触到位运算的知识。\n - 而1008也是强行卡题意,给的样例不规范,还不如只给一个。另外也有很多同学并不知道EOF判输入结束。\n4. 从所有题目通过率来看,\n - 1001、1003、1005、1007、1008、1011是正常水平在七天时间内能做出的。\n - 1009尽管是入门级dp,但也涉及了算法,虚高是因为生源有部分接触过OI,以及的确简单,能间接搜到答案。\n5. 从难度上看,\n - 1002爆冷是正常,原因大家都懂。\n - 1004的确算是较难的了,之后改题面应该称得上全场最难。\n - 1006爆冷正常,因为我也不会做(逃),好吧是因为涉及了计算几何,不应该出现在新生赛中。\n - 1010爆冷是意料之外,也是情理之中,这种卡题意挖坑的题必须找出题人背锅。\n6. 1001、1008是两个签到题。预计决赛名额定在解出两题以上。\n7. 我校出题质量一年比一年差,迟早要完。\n\n### 历届新生赛\u0026别人的新生赛\n1. 华南师大2014新生赛:http://3.scnuacm2015.sinaapp.com/?p\u003d38\n2. 广工2016新生决赛网络同步赛重现:http://gdutcode.sinaapp.com/contest.php?cid\u003d1051\n3. ....\n\n### 建议、意见、吐槽\n欢迎在下方评论区提出问题,12月内我都会回复and更新。\n\n\u003cbr/\u003e\u003cbr/\u003e\u003cbr/\u003e\n\u003e \u003cp\u003e本文\u003ca href\u003d\"http://creativecommons.org/licenses/by-nc-sa/4.0/\" rel\u003d\"license\"\u003e基于\u003cimg style\u003d\"border-width: 0;\" src\u003d\"http://files.cnblogs.com/files/BlackStorm/by-nc-sa_4.0_88x31.gif\" alt\u003d\"知识共享许可协议\" /\u003e知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议\u003c/a\u003e发布,欢迎引用、转载或演绎,但是必须保留本文的署名\u003ca title\u003d\"BlackStorm\" href\u003d\"http://creativecommons.org/licenses/by-nc-sa/4.0/\" rel\u003d\"license\"\u003eBlackStorm\u003c/a\u003e以及本文链接\u003ca href\u003d\"http://www.cnblogs.com/BlackStorm/p/SCNUCPC_2016_For_Freshman_Preliminary_Solution.html\"\u003ehttp://www.cnblogs.com/BlackStorm/p/SCNUCPC_2016_For_Freshman_Preliminary_Solution.html\u003c/a\u003e,且未经许可不能用于商业目的。如有疑问或授权协商请\u003ca href\u003d\"mailto:hsxfjames@gogobst.com\" target\u003d\"_blank\"\u003e与我联系\u003c/a\u003e。\u003c/p\u003e"}}]}