The first time I entered DIV1, I was decisively abused and couldn't help. Solve DIV2 first after the competition
A. System of Equations
Ask a * a + B = m a + B * B = n, the solution a, B, and how many groups are there, because a and B are not negative, in addition, the range of m and n is less than 1000, and direct violence means 1000*1000.
[Cpp]
# Include <iostream>
# Include <cstring>
# Include <queue>
# Include <cstdio>
# Include <cmath>
# Include <algorithm>
# Define N 55
# Define inf 1 <29
# Define MOD 9973.
# Deprecision Max 301
# Define LL long
# Define eps 1e-7
# Define zero (a) fabs (a) <eps
# Define equal (a, B) zero (a-B)
Using namespace std;
Int main (){
Int n, m;
While (scanf ("% d", & n, & m )! = EOF ){
Int cnt = 0;
For (int I = 0; I <= 1000; I ++)
For (int j = 0; j <= 1000; j ++)
If (I * I + j = n & j * j + I = m)
Cnt ++;
Printf ("% d \ n", cnt );
}
Return 0;
}
B. Hometask
A number is an integer that can be divided into 2, 3, and 5, and must be the largest.
The last digit must be 0, and the last digit must be 3. The sum of all digits must be a multiple of 3.
First, determine whether there is 0. If not, output-1.
Sort all numbers in descending order (because the question requires the largest integer)
Next, let's see if all the digits and values are multiples of 3. If yes, they are output in order.
Next, some numbers may be deleted. Deleting one digit is certainly larger than deleting two digits, and only one or two digits can be deleted.
If the number and modulo 3 are 1, delete a number as small as possible, modulo 3 is 1, for (int I = 1; I <10; I + = 3 ), if such a number exists, delete it.
If it does not exist, it is possible to delete the two-digit modulo, and the two-digit modulo 3 to be deleted are both 2.
If the number and modulo 3 are 2, delete a number as small as possible, modulo 3 is 2, for (int I = 2; I <10; I + = 3 ), if such a number exists, delete it.
If this parameter does not exist, two modulo values may be deleted, and the two modulo 3 values are all 1. from small to large, two modulo values are deleted.
If none of the above conditions exists,-1 is output.
During Processing, do not output 000000, including the deleted output.
The code is very shi.
C. Game
DIV1's question A is that the network flow has been under construction and is weak.
It can be found that 1-> 2 2 2-> 3 3-> 1 is 1, and the rest is 2. In fact, the first digit shifts right of the loop to 1, and the two digits are 2.
Add a little greedy, enumerate the first machine, first do what you can do, and add all the unlimitedly added to the queue.
If no task can be performed on this machine, it will go to the next one, and the time will be + 1 until all tasks are completed. That is to say, after selecting a machine, you can do everything you can to avoid the transfer cost. After you have done a task, you need to add other unlimitedly added servers to the queue.
[Cpp]
# Include <iostream>
# Include <cstring>
# Include <queue>
# Include <cstdio>
# Include <cmath>
# Include <algorithm>
# Define N 55
# Define inf 1 <29
# Define MOD 9973.
# Deprecision Max 301
# Define LL long
# Define eps 1e-7
# Define zero (a) fabs (a) <eps
# Define equal (a, B) zero (a-B)
Using namespace std;
Bool mat [205] [205];
Int c [205], n;
Int slove (int s ){
Int deg [205];
Memset (deg, 0, sizeof (deg ));
Queue <int> que [3];
For (int I = 1; I <= n; I ++ ){
For (int j = 1; j <= n; j ++)
If (mat [I] [j])
Deg [I] ++;
If (deg [I] = 0)
Que [c [I]. push (I );
}
Int ret = 0, cnt = n;
Bool flag [205];
Memset (flag, true, sizeof (flag ));
While (! Que [0]. empty () |! Que [1]. empty () |! Que [2]. empty ()){
If (que [s]. empty () {s = (s + 1) % 3; ret ++; continue ;}
Int u = que [s]. front ();
Que [s]. pop ();
Cnt --;
Flag [u] = false;
For (int I = 1; I <= n; I ++ ){
If (mat [I] [u]) {
Deg [I] --;
If (deg [I] = 0 & flag [I])
Que [c [I]. push (I );
}
}
If (cnt = 0)
Break;
}
Return ret;
}
Int main (){
While (scanf ("% d", & n )! = EOF ){
For (int I = 1; I <= n; I ++ ){
Scanf ("% d", & c [I]);
C [I] --;
}
For (int I = 1; I <= n; I ++ ){
Int k, u;
Scanf ("% d", & k );
While (k --){
Scanf ("% d", & u );
Mat [I] [u] = true;
}
}
Int ans = inf;
For (int I = 0; I <3; I ++)
Ans = min (ans, slove (I) + n );
Printf ("% d \ n", ans );
}
Return 0;
}
D. Numbers
Combined count. The leading 0 is not allowed, so we should consider it in reverse order. From 9 to 0, dp [I] [j] indicates that the number of I is considered and the length is j.
Then enumerate the number of digits of the current number. Pay attention to the lower limit. In the code, the number is j, and the number is j-k. Then the previous k values are obtained, that is, dp [I + 1] [k] * c [j] [k]. The former is the number of the previous round, the latter indicates that the previous k digits are extracted from the j position, and the remaining j-k digits are placed in the current number.
Note that the number 0 must be special. Leading 0 is not allowed.
[Cpp]
# Include <iostream>
# Include <cstring>
# Include <queue>
# Include <cstdio>
# Include <cmath>
# Include <algorithm>
# Define N 305
# Define inf 1 <29
# Define MOD 1000000007.
# Deprecision Max 301
# Define LL _ int64
# Define eps 1e-7
# Define zero (a) fabs (a) <eps
# Define equal (a, B) zero (a-B)
Using namespace std;
LL dp [11] [1, 205], c [2, 205] [2, 205];
Int n, a [10];
Int main (){
While (scanf ("% d", & n )! = EOF ){
For (int I = 0; I <10; I ++)
Scanf ("% d", & a [I]);
For (int I = 0; I <= n; I ++ ){
C [I] [0] = c [I] [I] = 1;
For (int j = 1; j <I; j ++)
C [I] [j] = (c [I-1] [J-1] + c [I-1] [j]) % MOD;
}
Memset (dp, 0, sizeof (dp ));
Dp [10] [0] = 1;
For (int I = 9; I> = 0; I --){
For (int j = n; j> = 0; j --)
For (int k = j-a [I]; k> = 0; k --)
If (I) dp [I] [j] = (dp [I] [j] + dp [I + 1] [k] * c [j] [k]) % MOD;
Else if (j & k) dp [I] [j] = (dp [I] [j] + dp [I + 1] [k] * c [J-1] [k-1]) % MOD;
}
LL ans = 0;
For (int I = 0; I <= n; I ++)
Ans = (ans + dp [0] [I]) % MOD;
Printf ("% I64d \ n", ans );
}
Return 0;
}
E. Relay Race
NOIP 2008 uploads a piece of paper. One-way is very simple. Two-way users can consider two people from () to (n, n) at the same time ). Then we can use four-dimensional representation to represent the positions of two people, but N reaches 300, which is not four-dimensional.
Because two people are moving at the same time, x1 + y1 = x2 + y2. We can also use dp [I] [j] [k] To represent step I. The two are row j and row k respectively, then the first person is in column I-j + 2, and the second person is in column I-k + 2.
Do not cross the data during transfer, and do not retrieve the data when it reaches the same position.
It may be negative. Pay attention to initialization.
[Cpp]
# Include <iostream>
# Include <cstring>
# Include <queue>
# Include <cstdio>
# Include <cmath>
# Include <algorithm>
# Define N 305
# Define inf 1 <29
# Define MOD 9973.
# Deprecision Max 301
# Define LL long
# Define eps 1e-7
# Define zero (a) fabs (a) <eps
# Define equal (a, B) zero (a-B)
Using namespace std;
Int dp [N <1] [N] [N];
Int a [N] [N], n;
Int way [4] [2] = {0, 0}, {0, 1}, {1, 0}, {1, 1 }};
Int main (){
While (scanf ("% d", & n )! = EOF ){
For (int I = 1; I <= n; I ++)
For (int j = 1; j <= n; j ++)
Scanf ("% d", & a [I] [j]);
Memset (dp, 0x81, sizeof (dp ));
Dp [0] [1] [1] = a [1] [1];
For (int I = 1; I <= 2 * N-2; I ++)
For (int j = 1; j <= I + 1 & j <= n; j ++)
For (int k = j; k <= I + 1 & k <= n; k ++ ){
For (int r = 0; r <4; r ++)
Dp [I] [j] [k] = max (dp [I] [j] [k], dp [I-1] [j-way [r] [0] [k-way [r] [1]);
Dp [I] [j] [k] + = a [j] [I-j + 2] + a [k] [I-k + 2]-(j = k? A [k] [I-k + 2]: 0 );
}
Printf ("% d \ n", dp [2 * N-2] [n] [n]);
}
Return 0;
By ACM_cxlove