您的位置:首页 > 其它

The 9th SWJTU-CPC Qualification Round Tutorials

2013-04-13 20:06 423 查看
You can click on the following website link to visit the contest-homepage quickly.
http://acm.swjtu.edu.cn/JudgeOnline/showcontest?contest_id=1135
There are 10 programming problems in this contest, some of which are basal.

Solutions for the problems will be represented in the following descriptions. 

Well,
Problem G, I, J, and K
are recommended by me.

Even some problems provided by other smart guys are also discussed here, I can not make sure that my approach is correct. Therefore, any questions or suggestions will be welcomed.

Problem A, this problem is very easy to solve. I think, for some guys, the most difficult problem is how to terminate the input, or read
data consecutively. Well, I suggest you try to solve these problems at first according to the following problem-links:
http://acm.swjtu.edu.cn/JudgeOnline/showcontest?contest_id=1087
int a, b; while( scanf("%d %d", &a, &b) == 2 ) {
printf("%d\n", a + b);
}


Problem B, the mathematical model of this problem is to judge an indeterminate equation, i.e.

a * x + b * y = c
Well, for the problem, "up" is corresponding to "a", "down" corresponds to "b", and "num" is corresponding to "c", the question is to check "is there an integer-root for the equation ?"

The answer to the question described above is that, if the equation has roots, then the greast common divisor (namely GCD or gcd) between a and b, denoted by d ( = gcd(a, b)), can devide
c, i.e.

c mod gcd(a, b) = 0

#include<cstdio>

int gcd(int a, int b)
{
if( a == 0 ) return b;
if( b == 0 ) return a;
return gcd(b, a % b);
}

int main()
{
int nt; scanf("%d", &nt); while( (nt --) > 0 ) {
int up, down, num; scanf("%d %d %d", &up, &down, &num);
if( up == 0 && down == 0 ) printf("%s\n", num == 0 ? "YES" : "NO");
else if( up == 0 ) printf("%s\n", num == 0 ? "YES" : "NO");
else {
int d = gcd(up, down);
d = num % d;
printf("%s\n", d == 0 ? "YES" : "NO");
}
}
return 0;
}

Individual test data:

Input

3
0 0 1
1 0 1
0 1 1

Output

NO
YES
NO


Problem C, we can not solve this problem as well as Problem B. We can try to exploit recursive algorithm to complete it. The pseudo-code
is as follows.

void dfs(int cur)
{
if( vst[cur] ) return ; vst[cur] = 1;
if( cur + up <= top ) dfs(cur + up);
if( cur - down >= 0 ) dfs(cur - down);
}

Individual test data:

Input

3
10 1 2 3
2 1 3 3
2 1 1 1

Output

NO
YES
NO


Problem D, it is easy to solve, just do it.

int nt; scanf("%d", &nt); while( (nt --) > 0 ) {
scanf("%d", &N); for(int i = 0; i < N; i ++) scanf("%d", A + i);
sort(A, A + N); printf("%d\n", unique(A, A + N) - A);
}

Individual test data:

Input

3
3
2013 2013 2013
2
2013 2013
7
2013 2013 2012 2012 2012 2011 2011

Output

1
1
3


Problem E, for the front i (1 <= i <= N) integers, namely, 

A(1), A(2), A(3), ..., A(i)
assume that , its optimal order is

A(op(1)), A(op(2)), A(op(3)), ..., A(op(i))
where, {op(1), op(2), op(3), ..., op(i)} is one permutation of {1, 2, 3, ..., i}.

Then, for the next integer, i.e. A(i+1), we can enumerate the insertion-position from 1 to (i + 1) in order to find the next optimal order.

For example, consider the sequence {2013, 4, 13, 97, 8, 9}, and we can obtain the final answer according to the following descriptions.

The first step, we have {2013};

The second step, we have {2013} before and now an integer "4", we enumerate the insertion-position:

1. {"4", 2013}

2. {2013, "4"}

and we can get the optimal order: {4, 2013};

The third step, we have {4, 2013} before and now an integer "13", we enumerate the insertion-position:

1. {"13", 4, 2013}

2. {4, "13", 2013}

3. {4, 2013, "13"}

and we can get the optimal order: {4, 2013, 13};

The fouth step, we have {4, 2013, 13} before and now an integer "97", we enumerate the insertion-position:

1. {"97", 4, 2013, 13}

2. {4, "97", 2013, 13}

3. {4, 2013, "97", 13}

4. {4, 2013, 13, "97"}

and we can get the optime order: {97, 4, 2013, 13};

The fifth step, we have {97, 4, 2013, 13} before and now an integer "8", we enumerate the insertion-position:

1. {"8", 97, 4, 2013, 13}

2. {97, "8", 4, 2013, 13}

3. {97, 4, "8", 2013, 13}

4. {97, 4, 2013, "8", 13}

5. {97, 4, 2013, 13, "8"}

and we can get the optime order: {97, 8, 4, 2013, 13};

The sixth step, we have {97, 8, 4, 2013, 13} before and now an integer "9", we enumerate the insertion-position:

1. {"9", 97, 8, 4, 2013, 13}

2. {97, "9", 8, 4, 2013, 13}

3. {97, 8, "9", 4, 2013, 13}

4. {97, 8, 4, "9", 2013, 13}

5. {97, 8, 4, 2013, "9", 13}

6. {97, 8, 4, 2013, 13, "9"}

Finally, we can obtain the optimal sequence: {9, 97, 8, 4, 2013, 13}, 

and the answer: 99784201313.

Individual test data:

Input

10
2
985 98
3
985 985 98
2
211 9
3
985 9 90
3
973 98 9
4
979 97 9 8
4
90 80 9 8
5
90 80 9 8 98
1
1000
5
9 80 89 89 998

Output

98985
98985985
9211
998590
998973
9979978
990880
99890880
1000
9998898980


Problem F, we can use binary search to find the correct answer. Another critical problem
is how to compute the number of integers that can not devided by 3 or 5. Initally, we have 

A(n) = 4*n - 1 (n >= 1).
It is easy to find that, for any {A(i), A(i + 1), A(i + 2)}, there must be only one integer can be devied by 3;

and, for any {A(i), A(i + 1), A(i + 2), A(i + 3), A(i + 4)}, there must be only one integer can be devided by 5;

and, for any {A(i), A(i + 1), ..., A(i + 14)}, there must be only one integer can be devided by 15.

Let h(n) denote the number of integers that are no more than n and can not be devided by 3 or 5, f3(n) denote the number of integers that are no more than n and can be devided by 3, the same
with f5(n), and f15(n). It is clearly that

h(n) = n - f3(n) - f5(n) + f15(n)
Thus, I think you can try to compute f3(n), f5(n), and f15(n) by yourself.

#include<cstdio>
#include<cstring>

typedef long long i64d;

i64d calc(i64d N)
{
i64d f3 = N / 3LL + (N % 3LL != 0LL);
i64d f5 = N / 5LL + (N % 5LL >= 4LL);
i64d f15 = N / 15LL + (N % 15LL >= 4LL);
return N - f3 - f5 + f15;
}

int main()
{
int nt; scanf("%d", &nt); while( (nt --) > 0 ) {
i64d N; scanf("%lld", &N);
i64d l = 1LL, r = 10LL * N, mid, res = -1LL;
while( l <= r ) {
mid = (l + r) >> 1LL;
if( calc(mid) >= N ) res = mid, r = mid - 1LL;
else l = mid + 1LL;
}
printf("%lld\n", 4LL * res - 1LL);
}
return 0;
}


Individual test data:
Input

20
10086
10087
10088
10089
10090
10091
10092
10093
10094
10095
10096
10097
10098
10099
10100
999999999
999999998
999999997
999999996
999999995


Output

75643
75647
75659
75667
75671
75679
75683
75691
75703
75707
75719
75727
75731
75739
75743
7499999987
7499999983
7499999971
7499999963
7499999959


Problem G, the most simple problem, except Problem A? Well, nothing can be told.

Problem H, the answer is equal to: Rounded-up(the sum of number of book pages / read-number of book pages per day).

int nt; scanf("%d", &nt); while( (nt --) > 0 ) {
int N, M; scanf("%d %d", &N, &M);
int val, sum = 0; for(int i = 0; i < N; i ++) {
scanf("%d", &val);  sum += val;
} int res = sum / M; if( sum % M ) res ++;
printf("%d\n", res);
}

Individual test data:

Input

1
3 3
1 2 2

Output

2


Problem I, Simulation.

Problem J, Simulation.

Individual test data:
Input
20
10
4 3 2 1 3 2 1 2 1 1
4
1 2 1 2
1
-1
2
-1 -1
3
1 2 2
5
1 2 3 3 4
6
2 1 3 3 4 4
6
-2 -1 -3 -3 -4 -4
10
0 0 0 0 0 0 0 0 0 0
10
1 1 1 1 1 2 2 2 2 2
10
1 1 1 1 2 2 2 2 2 2
10
1 1 1 1 2 2 2 2 3 3
10
1 2 3 6 5 4 7 8 9 6
6
2 2 3 3 1 1
7
2 2 2 3 3 1 1
9
2 2 3 3 1 1 6 6 6
10
2 2 2 3 3 1 1 7 7 7
2
-1 -2
4
-1 -1 -2 -2
5
-1 -2 -3 -2 -3


Output

4 1 2 3 4
2 1 2
1 -1
1 -1
2 2 1
4 3 1 2 4
4 3 4 1 2
4 -4 -3 -2 -1
1 0
2 1 2
2 2 1
3 1 2 3
9 6 1 2 3 4 5 7 8 9
3 1 2 3
3 2 1 3
4 6 1 2 3
4 2 7 1 3
2 -2 -1
2 -2 -1
3 -3 -2 -1


Thank you for your reading, 

any questions will be welcomed,

Sincerely,

Hzwu [At] SWJTU [At] 2013.4.13
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: