The 9th SWJTU-CPC Qualification Round Tutorials

来源:互联网 发布:mysql front5.3 乱码 编辑:程序博客网 时间:2024/05/04 05:59

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

30 0 11 0 10 1 1

Output

NOYESNO


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

310 1 2 32 1 3 32 1 1 1

Output

NOYESNO


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

332013 2013 201322013 201372013 2013 2012 2012 2012 2011 2011

Output

113


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

102985 983985 985 982211 93985 9 903973 98 94979 97 9 8490 80 9 8590 80 9 8 981100059 80 89 89 998

Output

9898598985985921199859099897399799789908809989088010009998898980


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

20100861008710088100891009010091100921009310094100951009610097100981009910100999999999999999998999999997999999996999999995


Output

75643756477565975667756717567975683756917570375707757197572775731757397574374999999877499999983749999997174999999637499999959


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

13 31 2 2

Output

2


Problem I, Simulation.


Problem J, Simulation.

Individual test data:

Input

20104 3 2 1 3 2 1 2 1 141 2 1 21-12-1 -131 2 251 2 3 3 462 1 3 3 4 46-2 -1 -3 -3 -4 -4100 0 0 0 0 0 0 0 0 0101 1 1 1 1 2 2 2 2 2101 1 1 1 2 2 2 2 2 2101 1 1 1 2 2 2 2 3 3101 2 3 6 5 4 7 8 9 662 2 3 3 1 172 2 2 3 3 1 192 2 3 3 1 1 6 6 6102 2 2 3 3 1 1 7 7 72-1 -24-1 -1 -2 -25-1 -2 -3 -2 -3

Output

4 1 2 3 42 1 21 -11 -12 2 14 3 1 2 44 3 4 1 24 -4 -3 -2 -11 02 1 22 2 13 1 2 39 6 1 2 3 4 5 7 8 93 1 2 33 2 1 34 6 1 2 34 2 7 1 32 -2 -12 -2 -13 -3 -2 -1




Thank you for your reading, 

any questions will be welcomed,

Sincerely,


Hzwu [At] SWJTU [At] 2013.4.13