虽然退役了,但偶尔水几题醒醒脑还是不错的=_=
1085 Intermediary 暂时还没做
Little A is one member of ACM team. He had just won the gold in World Final. To celebrate, he decided to invite all to have one meal. As bowl, knife and other tableware is not enough in the kitchen, Little A goes to take backup tableware in warehouse.
There are many boxes in warehouse, one box contains only one thing, and each box is marked by the name of things inside it. For example, if "basketball" is written on the box, which means the box contains only basketball.
With these marks, Little A wants to find out the tableware easily. So, the problem for you is to help him, find out all the tableware from all boxes in the warehouse.
There are many test cases. Each case contains one line, and one integer N at the first, N indicates that there are N boxes in the warehouse. Then Nstrings follow, each string is one name written on the box.
For each test of the input, output all the name of tableware.
3 basketball fork chopsticks 2 bowl letter
fork chopsticks bowl
The tableware only contains: bowl, knife, fork and chopsticks.
辽宁省赛2010
不可多说的水题
#include<bits/stdc++.h> using namespace std; int main() { ios::sync_with_stdio(false); cin.tie(0); int n; string name; set<string> s; s.insert("bowl"); s.insert("knife"); s.insert("fork"); s.insert("chopsticks"); while (cin >> n) { bool isFirst = true; for (int i=0; i<n; i++) { cin >> name; if (s.count(name)) { if (isFirst) { cout << name; isFirst = false; } else { cout << " " << name; } } } cout << "\n"; } return 0; } /************************************************************** Problem: 1081 User: yybird Language: C++ Result: 正确 Time:1 ms Memory:1700 kb ****************************************************************/
Little A gets to know a new friend, Little B, recently. One day, they realize that they are family 500 years ago. Now, Little A wants to know whether Little B is his elder, younger or brother.
There are multiple test cases.
For each test case, the first line has a single integer, n (n<=1000). The next n lines have two integers a and b (1<=a,b<=2000) each, indicating b is the father of a. One person has exactly one father, of course. Little A is numbered 1 and Little B is numbered 2.
Proceed to the end of file.
For each test case, if Little B is Little A’s younger, print “You are my younger”. Otherwise, if Little B is Little A’s elder, print “You are my elder”. Otherwise, print “You are my brother”. The output for each test case occupied exactly one line.
5 1 3 2 4 3 5 4 6 5 6 6 1 3 2 4 3 5 4 6 5 7 6 7
You are my elder You are my brother
辽宁省赛2010
看谁层数多,显然的水题。
#include<bits/stdc++.h> using namespace std; int p[2000+10]; void init() { for (int i=0; i<=2000; i++) p[i] = i; } int main() { int n, a, b; ios::sync_with_stdio(false); cin.tie(0); while(cin >> n) { init(); for (int i=0; i<n; i++) { cin >> a >> b; p[a] = b; } int cnt1=0, cnt2=0; for (int i=1; p[i]!=i; i=p[i], cnt1++); for (int i=2; p[i]!=i; i=p[i], cnt2++); if (cnt1 < cnt2) cout << "You are my younger\n"; else if (cnt1 > cnt2) cout << "You are my elder\n"; else cout << "You are my brother\n"; } return 0; } /************************************************************** Problem: 1082 User: yybird Language: C++ Result: 正确 Time:18 ms Memory:1700 kb ****************************************************************/
Digital clock use 4 digits to express time, each digit is described by 3*3 characters (including”|”,”_”and” “). Now given the current time, please tell us how can it be expressed by the digital clock.
There are several test cases.
Each case contains 4 integers in a line, separated by space.
Proceed to the end of file.
For each test case, output the time expressed by the digital clock such as Sample Output.
1 2 5 6 2 3 4 2
_ _ _ | _||_ |_ ||_ _||_| _ _ _ _| _||_| _| |_ _| ||_
The digits showed by the digital clock are as follows: _ _ _ _ _ _ _ _ | _| _||_||_ |_ ||_||_|| | ||_ _| | _||_| ||_| _||_|
来源
辽宁省赛2010
前几题真是又短又快啊...
#include<bits/stdc++.h> using namespace std; string num[] = { " _ _ _ _ _ _ _ _ ", "| | | _| _||_||_ |_ ||_||_|", "|_| ||_ _| | _||_| ||_| _|" }; int main() { int n, a, b, c, d; ios::sync_with_stdio(false); cin.tie(0); while(cin >> a >> b >> c >> d) { for (int i=0; i<3; i++) { cout << num[i][a*3] << num[i][a*3+1] << num[i][a*3+2] << num[i][b*3] << num[i][b*3+1] << num[i][b*3+2] << num[i][c*3] << num[i][c*3+1] << num[i][c*3+2] << num[i][d*3] << num[i][d*3+1] << num[i][d*3+2] << "\n"; } } return 0; } /************************************************************** Problem: 1083 User: yybird Language: C++ Result: 正确 Time:1 ms Memory:1692 kb ****************************************************************/
The National Intelligence Council of Nation X receives a piece of credible information that Nation Y will send spies to steal Nation X’s confidential paper. So the commander of The National Intelligence Council take measures immediately.
He will investigate people who will come into Nation X. At the same time, there are two List in the Commander’s hand, one is full of spies that Nation Y will send to Nation X, and the other one is full of spies that Nation X has sent to Nation Y before. There may be some overlaps of the two list. Because the spy may act two roles at the same time, which means that he may be the one that is sent from Nation X to Nation Y, we just call this type a “dual-spy”. So Nation Y may send “dual_spy” back to Nation X, and it is obvious now that it is good for Nation X, because “dual_spy” may bring back Nation Y’s confidential paper without worrying to be detention by Nation Y’s frontier. So the commander decides to seize those that are sent by Nation Y, and let the ordinary people and the “dual_spy” in at the same time .So can you decide a list that should be caught by the Commander?
A: the list contains that will come to the Nation X’s frontier.
B: the list contains spies that will be sent by Nation Y.
C: the list contains spies that were sent to Nation Y before.
There are several test cases.
Each test case contains four parts, the first part contains 3 positive integers A, B, C ( A, B, C are all less than 1000), and A is the number which will come into the frontier. B is the number that will be sent by Nation Y, and C is the number that Nation X has sent to Nation Y before. The second part contains A strings, the name list of that will come into the frontier. The third part contains B strings, the name list of that are sent by Nation Y. The fourth part contains C strings, the name list of the “dual_spy”. There will be a blank line after each test case.
There won’t be any repetitive names in a single list, if repetitive names appear in two lists, they mean the same people.
Output the list that the commander should caught (in the appearance order of the lists B).if no one should be caught, then , you should output “No enemy spy”.
8 4 3 Zhao Qian Sun Li Zhou Wu Zheng Wang Zhao Qian Sun Li Zhao Zhou Zheng 2 2 2 Zhao Qian Zhao Qian Zhao Qian
Qian Sun Li No enemy spy
辽宁省赛2010
找出存在于集合A和集合B但不存在于集合C的元素
#include<bits/stdc++.h> using namespace std; int main() { ios::sync_with_stdio(false); cin.tie(0); int a, b, c; string name; while (cin >> a >> b >> c) { set<string> s; vector<string> v; for (int i=0; i<a; i++) { cin >> name; s.insert(name); } for (int j=0; j<b; j++) { cin >> name; if (s.count(name)) v.push_back(name); } for (int k=0; k<c; k++) { cin >> name; for (int i=0; i<v.size(); i++) { if (v[i] == name) { v.erase(v.begin()+i); } } } if (v.empty()) cout << "No enemy spy\n"; else { int sz = v.size(); cout << v[0]; for (int i=1; i<sz; i++) cout << " " << v[i]; cout << "\n"; } } return 0; } /************************************************************** Problem: 1084 User: yybird Language: C++ Result: 正确 Time:1 ms Memory:1704 kb ****************************************************************/
It is widely known that any two strangers can get to know each other through at most six other people. Now let’s prove this.
In the country Intermediary Conducts Personal Communications (ICPC), there are up to n (2<=n<=100) ordinary people conveniently numbered from0 to n-1. They don’t know each other, or, in other words, they are strangers. The only way they can communicate with each other is through the government, which, in fact, is an intermediary agency. The government consists of up to m (1<=m<=9) employees conveniently numbered from 0 tom-1. Suppose employee z can introduce person x to person y at a cost of d dollars. If this is the first time in a day that employee z introduce one person to another, he will only require d dollars. For the second time, he will require d dollars plus extra e dollars as his tip. For the third time and more, he will require d dollars plus extra f dollars. He is not dared to require any more than that since the strange country is somewhat democratic. And if person x is able to communicate with person t and person t is able to communicate with person y, then person t is always willing to transfer messages from person x to person y, at no charge. Of course, the intermediary fees are all paid by person x. Notice that employee z being able to introduce person x to person y doesn’t mean he can introduce person y to person x.
Now person 0 has to send a message to person n-1 in one day. If all employees have just started to work, what is the minimum cost for person 0?
For each test case, the first line contains three integers, n, m and q, where q is the number of intermediary relationships and q is at most 10,000. The second line has m integers, each indicating the value e of every employee, in the range [0, 100]. The third line has m integers too, each indicating the value f of every employee, in the range [e, 200]. The next q lines each contains four integers, x, y, z and d, indicating that employee z can introduce person x to person y requiring d dollars, where 1<=d<=200. There is a blank line after each test case.
Proceed to the end of file.
For each test case, print one integer on a single line, giving the minimum cost. If it is impossible, print -1.
3 2 2 1 1 2 2 0 1 0 1 1 2 1 2 5 1 4 1 2 0 1 0 1 1 2 0 1 2 3 0 1 3 4 0 1
3 9
辽宁省赛2010
还没做...
This English game is a simple English words connection game.
The rules are as follows: there are N English words in a dictionary, and every word has its own weight v. There is a weight if the corresponding word is used. Now there is a target string X. You have to pick some words in the dictionary, and then connect them to form X. At the same time, the sum weight of the words you picked must be the biggest.
There are several test cases. For each test, N (1<=N<=1000) and X (the length of X is not bigger than 10000) are given at first. Then N rows follow. Each row contains a word wi (the length is not bigger than 30) and the weight of it. Every word is composed of lowercases. No two words in the dictionary are the same.
For each test case, output the biggest sum weight, if you could not form the string X, output -1.
1 aaaa a 2 3 aaa a 2 aa 5 aaa 6 4 abc a 1 bc 2 ab 4 c 1 3 abcd ab 10 bc 20 cd 30 3 abcd cd 100 abc 1000 bcd 10000
8 7 5 40 -1
辽宁省赛2010
DP+AC自动机。
这道题正常人的第一反应肯定就是DP,而且这个看起来还非常好写。但是,捏了下复杂度后发现会超时:10000*1000*30=3亿,一秒是妥妥的不够的。但是这个复杂度似乎超得不是很多,于是乎看看能不能优化。最先想到的就是用hash把30砍成1,但是发现只要有substr()这个操作在,这个30根本砍不了。后来,注意到题目的数据是很显然的“一个长串,N多个很短的子串”模式,于是就想到了用AC自动机进行字符串匹配部分的优化,代码如下:
#include<bits/stdc++.h> using namespace std; const int MAXCHILD = 26; // 每个结点的最大子结点数(仅小写字母) const int MAXNODE = 1010*30+10; // 总结点的最大数量 int N, sz; // sz: size of trie; int v[1010], d[10010], f[MAXNODE]; // 分别为:单词权重,dp数组,失配数组 int last[MAXNODE]; // suffix link 记录的是失配指针往回走时遇到的下一个单词结点编号 char w[35], X[10010]; struct Trie { int depth, isEnd; // isEnd: 保存的是编号为几的字符串的结尾结点,在每次结点被创建的时候会被置0 int next[MAXCHILD]; // 下一个结点,在每次结点被创建的时候会被全部置为0 } node[MAXNODE]; struct ACAutomata { void init() { sz = 1; memset(node[0].next, 0, sizeof(node[0].next)); // 头结点的儿子结点置为0 } void newNode(int u) { memset(node[sz].next, 0, sizeof(node[sz].next)); node[sz].depth = node[u].depth+1; node[sz].isEnd = 0; // 新创建的结点还不是某个单词的结尾 } int idx(char c) { return c-'a'; } void insert(char *s, int v) { // 插入字符串。v代表该字符串的编号,必须非0 int u = 0, n = strlen(s); // u起指针作用 for(int i = 0; i < n; i++) { int c = idx(s[i]); if(!node[u].next[c]) { newNode(u); // 以u为父节点新建一个子节点 node[u].next[c] = sz++; // 新结点的位置,注意放入的是sz不是sz+1 } u = node[u].next[c]; // 指针移向下一个结点 } node[u].isEnd = v; // 插入完成后,指针所在位置是编号为v的字符串的末尾 } void gao(int i, int j, int c) { int s = i-node[j].depth; // start position if (s==-1 || d[s+1]) d[i+1] = max(d[i+1], d[s+1]+v[node[j].isEnd]); if (last[j]) gao(i, last[j], c); } void find(char* T) { int n = strlen(T); int j = 0; // 当前结点编号,初始为根结点 for(int i = 0; i < n; i++) { // i是文本串当前指针 int c = idx(T[i]); while(j && !node[j].next[c]) j = f[j]; // 顺着失配边走,直到可以匹配 j = node[j].next[c]; if (node[j].isEnd) gao(i, j, c); else if (last[j]) gao(i, last[j], c); } } void getFail() { queue<int> q; f[0] = 0; for(int c = 0; c < MAXCHILD; c++) { int u = node[0].next[c]; if(u) { f[u] = 0; q.push(u); last[u] = 0;} } while(!q.empty()) { int r = q.front(); q.pop(); for(int c = 0; c < MAXCHILD; c++) { int u = node[r].next[c]; if(!u) continue; q.push(u); int v = f[r]; while(v && !node[v].next[c]) v = f[v]; f[u] = node[v].next[c]; last[u] = node[f[u]].isEnd ? f[u] : last[f[u]]; } } } }; int main() { ios::sync_with_stdio(false); cin.tie(0); ACAutomata ac; while (cin >> N >> X) { int len = strlen(X); memset(d, 0, sizeof(d)); ac.init(); for (int i=1; i<=N; i++) { cin >> w >> v[i]; ac.insert(w, i); } ac.getFail(); ac.find(X); if (d[len]) cout << d[len] << "\n"; else cout << "-1\n"; } return 0; } /************************************************************** Problem: 1086 User: yybird Language: C++ Result: 正确 Time:131 ms Memory:5304 kb ****************************************************************/
后来对比了下网上的代码,别人直接用Trie进行查询,代码比我短好多,耗时也比我短,简直无地自容。
Paula and Tai are couple. There are many stories between them. The day Paula left by airplane, Tai send one message to telephone 2200284, then, everything is changing… (The story in “the snow queen”).
After a long time, Tai tells Paula, the number 220 and 284 is a couple of friends number, as they are special, all divisors of 220’s sum is 284, and all divisors of 284’s sum is 220. Can you find out there are how many couples of friends number less than 10,000. Then, how about 100,000, 200,000 and so on.
The task for you is to find out there are how many couples of friends number in given closed interval [a,b]。
There are several cases.
Each test case contains two positive integers a, b (1<= a <= b <=5,000,000).
Proceed to the end of file.
For each test case, output the number of couples in the given range. The output of one test case occupied exactly one line.
1 100 1 1000
0 1
6 is a number whose sum of all divisors is 6. 6 is not a friend number, these number is called Perfect Number.
辽宁省赛2010
时间太短数字太大,但是显然答案很有限,这种情况下打个表就好
#include<bits/stdc++.h> using namespace std; int a, b, s[] = { 220,284, 1184,1210, 2620,2924, 5020,5564, 6232,6368, 10744,10856, 12285,14595, 17296,18416, 63020,76084, 66928,66992, 67095,71145, 69615,87633, 79750,88730, 100485,124155, 122265,139815, 122368,123152, 141664,153176, 142310,168730, 171856,176336, 176272,180848, 185368,203432, 196724,202444, 280540,365084, 308620,389924, 319550,430402, 356408,399592, 437456,455344, 469028,486178 }; int main() { ios::sync_with_stdio(false); cin.tie(0); while (cin >> a >> b) { int n = 0; for (int i=0; i<28; i++) if (s[i*2]>=a && s[i*2+1]<=b) n++; cout << n << "\n"; } return 0; } /************************************************************** Problem: 1087 User: yybird Language: C++ Result: 正确 Time:5 ms Memory:1692 kb ****************************************************************/
The life of Little A is good, and, he managed to get enough money to run a hotel. The best for him is that he need not go to work outside, just wait for the money to go into his pocket. Little A wants everything to be perfect, he has a wonderful plan that he will keep one most beautiful reception whose size is 1 (which means the reception is 1 square meter). There are other k rooms that have the same area, and the area is x^2, x is an integer; Little A wants his hotel to be a square. Little A is a good thinker, but not a good maker. As his poor performance on math, he cannot calculate the least area needed to build such a hotel of his will. Now, this task belongs to you, solve this problem to make Little A’s dream of Happy Hotel come true. Please be careful, the whole area should only contain k rooms, and the reception, there should not be any vacant place.
There are several test cases.
Each case contains only one integer k(1<=k<=1000), the number of rooms the hotel should have in one line.
Proceed to the end of file.
Output one integer d, means the hotel’s area is d^2 (If there is no answer, output “no solution”). The output of one test case occupied exactly one line.
1 2 3
no solution 3 2
辽宁省赛2010
连分数求佩尔方程最小解。
题目意思是说给定小于1000的正整数k, 存在正整数x, d,使得kx^2+1=d^2,求满足条件最小的d。将这个等式调换下位置,就是d^2-kx^2=1,显然是一个佩尔方程(pell方程, pell equation)。所以其实这道题就是求佩尔方程的最小特解。我们一般用连分数法来求这个特解,关于连分数法怎么求,网上有很多参考资料和论文,也有现成的模板。给出其中一个的链接:连分数法解佩尔方程特解
然后接下来就可以上代码了,基本上是套别人的连分数求特解的模板的,由于本题会超long long,所以用java方便些
importjava.util.Scanner; public class Main { public static void main(String[] args) { Scanner in = new Scanner(System.in); while(in.hasNextInt()) { int n = in.nextInt(); BigInteger N, p1, p2, q1, q2, a0,a1, a2, g1, g2, h1, h2, p, q; g1 = q2 = p1 = BigInteger.ZERO; h1 = q1 = p2 = BigInteger.ONE; a0 = a1 =BigInteger.valueOf((int)Math.sqrt(1.0*n)); BigInteger ans=a0.multiply(a0); if(ans.equals(BigInteger.valueOf(n))) { System.out.println("nosolution"); // 若为平方数则无解 } else { N = BigInteger.valueOf(n); while (true) { g2 =a1.multiply(h1).subtract(g1); h2 =N.subtract(g2.pow(2)).divide(h1); a2 = g2.add(a0).divide(h2); p =a1.multiply(p2).add(p1); q = a1.multiply(q2).add(q1); if(p.pow(2).subtract(N.multiply(q.pow(2))).compareTo(BigInteger.ONE) == 0) break; g1 = g2; h1 = h2; a1 = a2; p1 = p2; p2 = p; q1 = q2; q2 = q; } System.out.println(p); } } in.close(); } } /************************************************************** Problem: 1088 User: yybird Language: Java Result: 正确 Time:363 ms Memory:15208 kb ****************************************************************/
附上两道别的OJ上的连分数的题目:POJ2427 HDU2281
Little A has became fascinated with the game Dota recently, but he is not a good player. In all the modes, the rdsp Mode is popular on online, in this mode, little A always loses games if he gets strange heroes, because, the heroes are distributed randomly.
Little A wants to win the game, so he cracks the code of the rdsp mode with his talent on programming. The following description is about the rdsp mode:
There are N heroes in the game, and they all have a unique number between 1 and N. At the beginning of game, all heroes will be sorted by the number in ascending order. So, all heroes form a sequence One.
These heroes will be operated by the following stages M times:
Get out the heroes in odd position of sequence One to form a new sequence Two;
Let the remaining heroes in even position to form a new sequence Three;
Add the sequence Two to the back of sequence Three to form a new sequence One.
After M times' operation, the X heroes in the front of new sequence One will be chosen to be Little A's heroes. The problem for you is to tell little A the numbers of his heroes.
There are several test cases.
Each case contains three integers N (1<=N<1,000,000), M (1<=M<100,000,000), X (1<=X<=20).
Proceed to the end of file.
For each test case, output X integers indicate the number of heroes. There is a space between two numbers. The output of one test case occupied exactly one line.
5 1 2 5 2 2
2 4 4 3
In case two: N=5,M=2,X=2, the initial sequence One is 1,2,3,4,5. After the first operation, the sequence One is 2,4,1,3,5. After the second operation, the sequence One is 4,3,2,1,5. So,output 4 3.
辽宁省赛2010
打表(或手算)可得,当N为奇数时,第i个数字为i*(2^M)%N,当N为偶数时,则为i*(2^M)%(N+1),2^M可通过快速幂计算,然后就没然后了
#include<bits/stdc++.h> #define LL long long using namespace std; LL N, M, X; LL qpow(LL a, LL n) { LL ret = 1; while (n) { if (n & 1) ret = ret*a % N; n >>= 1; a = a*a % N; } return ret; } int main() { ios::sync_with_stdio(false); cin.tie(0); while (cin >> N >> M >> X) { if (!(N&1)) N++; LL fac = qpow(2, M); for (int i=1; i<=X; i++) cout << fac*i % N << " \n"[i==X]; } return 0; } /************************************************************** Problem: 1089 User: yybird Language: C++ Result: 正确 Time:2 ms Memory:1692 kb ****************************************************************/
另外附上两道湖南大学校赛的题目:
The Base 64 encoding is designed to represent arbitrary sequences of octets in a form that requires case sensitivity but need not be humanly readable.
65-character subset of US-ASCII is used, enabling 6 bits to be represented per printable character. (The extra 65th character, "=", is used to signify a special processing function.).
The encoding process represents 24-bit groups of input bits as output strings of 4 encoded characters. Proceeding from left to right, a 24-bit input group is formed by concatenating 3 8-bit input groups. These 24 bits are then treated as 4 concatenated 6-bit groups, each of which is translated into a single digit in the base 64 alphabet(Table 1).
Each 6-bit group is used as an index into an array of 64 printable characters. The character referenced by the index is placed in the output string.
Table 1: The Base 64 Alphabet
Value Encoding Value Encoding Value Encoding Value Encoding
0 A 17 R 34 i 51 z
1 B 18 S 35 j 52 0
2 C 19 T 36 k 53 1
3 D 20 U 37 l 54 2
4 E 21 V 38 m 55 3
5 F 22 W 39 n 56 4
6 G 23 X 40 o 57 5
7 H 24 Y 41 p 58 6
8 I 25 Z 42 q 59 7
9 J 26 a 43 r 60 8
10 K 27 b 44 s 61 9
11 L 28 c 45 t 62 +
12 M 29 d 46 u 63 /
13 N 30 e 47 v
14 O 31 f 48 w (pad) =
15 P 32 g 49 x
16 Q 33 h 50 y
Special processing is performed if fewer than 24 bits are available at the end of the data being encoded. A full encoding quantum is always completed at the end of a quantity. When fewer than 24 input bits are available in an input group, zero bits are added (on the right) to form an integral number of 6-bit groups. Padding at the end of the data is performed using the '=' character. Since all base 64 input is an integral number of octets, only the following cases can arise:
The final quantum of encoding input is an integral multiple of 24 bits; here, the final unit of encoded output will be an integral multiple of 4 characters with no "=" padding,
The final quantum of encoding input is exactly 8 bits; here, the final unit of encoded output will be two characters followed by two "=" padding characters, or
The final quantum of encoding input is exactly 16 bits; here, the final unit of encoded output will be three characters followed by one "=" padding character.
The first line of the input contains a single integer T (1 <= T <= 100), the number of test cases. Then T cases followed. Each case is a string(no empty string) in one line to be encoded.
For each test case, the encoding result of the string will be output.
4 What is your name i you yes
V2hhdCBpcyB5b3VyIG5hbWU= aQ== eW91 eWVz
湖南大学2008校赛
BASE64加密。
中规中矩的模拟吧,但是由于本人比较懒,这种能用Java秒杀的题坚决不用C++做。
import java.util.Scanner; import sun.misc.BASE64Encoder; public class Main { public static void main(String[] args) { Scanner in = new Scanner(System.in); int T = in.nextInt(); in.nextLine(); for (int i=0; i<T; i++) { String str = in.nextLine(); str = new BASE64Encoder().encode(str.getBytes()); str = str.replaceAll("\r", ""); str = str.replaceAll("\n", ""); System.out.println(str); } in.close(); } } /************************************************************** Problem: 1453 User: yybird Language: Java Result: 正确 Time:196 ms Memory:10992 kb ****************************************************************/
Both Xnby and Hekui like playing Chinese Chess. There are two sides: black and red in Chinese Chess. Each side take moves in turns. One day, they made a composition (Now, it's red's turn):
By the way, each side can only move the "Cannon"and the "Pawn". The cannon can move in straight lines at any distance (from one cross to another) if no other chess pieces block its way. And the pawn can only move forward, one unit per turn. (For the red, top-bottom is forward, and for the black, bottom-top).
After the discussion, they all agree that only when one side, for example, the black cannon is forced to take a horizonal move which makes the red cannon can get to the hemline of the black, then the red wins (See the following figure).
So, they make a few rules:
The cannon can only move forward. If one side has to move the "cannon" to left or right, he loses. Notice that it doesn't change situation if a cannon moves backward, because the opposite side can move its cannon forward for the same distance.
Only the pawns which haven't crossed the river can move and the pawn can only move forward. The distance between each pair of pawns (one red, one black) can not be less than 1.
The winner only depends on the distance m and n(between the pair of cannons in the same vertical line counting from the left side), S1,S2,S3 (between the pair of pawns' which not cross the river in the same vertical line counting from the left side).
(See the following figure)
Xnby and Hekui want to know: which side is the winner when each of them moves in the best strategy. To make it more interesting, m,n, S1,S2,S3are not limited by Chinese Chessboard, in other words, Chessboard of this game is large enough.
There are several test cases, each case in a single line which contains 5 integers separated by a blank: m, n,S1,S2,S3 , 0≤m,n≤1000000,1≤S1,S2,S3 ≤1000. The input terminates when one line contains a single negative integer, which needn't to be processed.
For each test case, output the winner (Red or Black).
4 1 2 2 1 0 0 1 1 1 -1
Red Black
湖南大学2008校赛
Nim博弈。
一行题。根据题目描述,很显然两个炮之间的距离可以看成两堆石子,并且这两堆石子都是可以取任意个。旁边三个兵(卒)由于每次只能移动一步(每次只能减1),所以可以把他们仨当成是一堆石子,显然取这堆石子的情况和其总量的奇偶性有关,即S1+S2+S3-3的奇偶性,若为奇数,则这堆石子等同于只有1个石子,若为偶数则等同于有0个石子。(所以整个游戏的最优策略:处于必胜态的一方每次只要模仿对方上一步的行动即可获胜,比如对方动兵(卒),我也动兵(卒),对方动炮,我也将另一列的炮移动一定距离并一直保持m=n,这样即可获胜。)最后按照Nim博弈的一般解法,将这三堆石子的总量进行异或即可。
接下来列出代码(判断S1+S2+S3-3的奇偶性等同于(S1+S2+S3-1)&1):
main(){int m,n,a,b,c;while(scanf("%d%d%d%d%d",&m,&n,&a,&b,&c)==5)puts(m^n^((a+b+c-1)&1)?"Red":"Black");} /************************************************************** Problem: 1454 User: yybird Language: C Result: 正确 Time:9 ms Memory:1092 kb ****************************************************************/