ccnu_2016_暑期模拟赛(1)

这套题本来是要当做第一周的模拟训练赛的,有几道题是CF上的,但是由于当时做题的时候CF崩了,所以临时换了一套题,没有用这套题。
今天把这套题补完了。

A. Devu, the Singer and Churu, the Joker

Devu is a renowned classical singer. He is invited to many big functions/festivals. Recently he was invited to “All World Classical Singing Festival”. Other than Devu, comedian Churu was also invited.

Devu has provided organizers a list of the songs and required time for singing them. He will sing n songs, ith song will take ti minutes exactly.

The Comedian, Churu will crack jokes. All his jokes are of 5 minutes exactly.

People have mainly come to listen Devu. But you know that he needs rest of 10 minutes after each song. On the other hand, Churu being a very active person, doesn’t need any rest.

You as one of the organizers should make an optimal sсhedule for the event. For some reasons you must follow the conditions:

The duration of the event must be no more than d minutes;
Devu must complete all his songs;
With satisfying the two previous conditions the number of jokes cracked by Churu should be as many as possible. 

If it is not possible to find a way to conduct all the songs of the Devu, output -1. Otherwise find out maximum number of jokes that Churu can crack in the grand event.
Input

The first line contains two space separated integers n, d (1 ≤ n ≤ 100; 1 ≤ d ≤ 10000). The second line contains n space-separated integers: t1, t2, …, tn (1 ≤ ti ≤ 100).
Output

If there is no way to conduct all the songs of Devu, output -1. Otherwise output the maximum number of jokes that Churu can crack in the grand event.
Examples
Input

3 30
2 2 1

Output

5

Input

3 20
2 1 1

Output

-1

Note

Consider the first example. The duration of the event is 30 minutes. There could be maximum 5 jokes in the following way:

First Churu cracks a joke in 5 minutes.
Then Devu performs the first song for 2 minutes.
Then Churu cracks 2 jokes in 10 minutes.
Now Devu performs second song for 2 minutes.
Then Churu cracks 2 jokes in 10 minutes.
Now finally Devu will perform his last song in 1 minutes. 

Total time spent is 5 + 2 + 10 + 2 + 10 + 1 = 30 minutes.

Consider the second example. There is no way of organizing Devu’s all songs. Hence the answer is -1.

【题目大意】
有一场演唱会。
有一个歌唱家准备了n首歌,这个歌唱家每唱完一首歌都需要休息10分钟。
还有一个喜剧演员是讲笑话的,他每讲一个笑话需要5分钟。不需要休息。
给出歌唱家唱这n首歌所需要的时间。

求在给定时间d内:
歌唱家唱完所有歌曲的前提下,喜剧演员最多可以将几个笑话。
如果歌唱家无法唱完所有歌曲。输出-1

【解法】先算出歌唱家唱完所有歌曲(加上休息的时间)需要多少时间,如果大于给定时间d,则输出-1
如果小于给定时间,那么将歌唱家任意两首歌之间休息的10分钟都让喜剧演员讲笑话

【AC代码】

#include 
#include 
#include 
#include 
#include 

using namespace std;

int a[110];

int main(){
    int n, d;
    while(scanf("%d%d", &n, &d) != EOF){
        int sum = 0;
        for(int i = 0; i < n; i++){
            scanf("%d", &a[i]);
            sum += a[i];
        }
        if(sum + 10 * (n - 1) > d){
            printf("-1\n");
        }
        else{
            printf("%d\n", (d - sum) / 5);
        }
    }
    return 0;
}

B. Devu, the Dumb Guy

Devu is a dumb guy, his learning curve is very slow. You are supposed to teach him n subjects, the ith subject has ci chapters. When you teach him, you are supposed to teach all the chapters of a subject continuously.

Let us say that his initial per chapter learning power of a subject is x hours. In other words he can learn a chapter of a particular subject in x hours.

Well Devu is not complete dumb, there is a good thing about him too. If you teach him a subject, then time required to teach any chapter of the next subject will require exactly 1 hour less than previously required (see the examples to understand it more clearly). Note that his per chapter learning power can not be less than 1 hour.

You can teach him the n subjects in any possible order. Find out minimum amount of time (in hours) Devu will take to understand all the subjects and you will be free to do some enjoying task rather than teaching a dumb guy.

Please be careful that answer might not fit in 32 bit data type.
Input

The first line will contain two space separated integers n, x (1 ≤ n, x ≤ 105). The next line will contain n space separated integers: c1, c2, …, cn (1 ≤ ci ≤ 105).
Output

Output a single integer representing the answer to the problem.
Examples
Input

2 3
4 1

Output

11

Input

4 2
5 1 2 1

Output

10

Input

3 3
1 1 1

Output

6

Note

Look at the first example. Consider the order of subjects: 1, 2. When you teach Devu the first subject, it will take him 3 hours per chapter, so it will take 12 hours to teach first subject. After teaching first subject, his per chapter learning time will be 2 hours. Now teaching him second subject will take 2 × 1 = 2 hours. Hence you will need to spend 12 + 2 = 14 hours.

Consider the order of subjects: 2, 1. When you teach Devu the second subject, then it will take him 3 hours per chapter, so it will take 3 × 1 = 3 hours to teach the second subject. After teaching the second subject, his per chapter learning time will be 2 hours. Now teaching him the first subject will take 2 × 4 = 8 hours. Hence you will need to spend 11 hours.

So overall, minimum of both the cases is 11 hours.

Look at the third example. The order in this example doesn’t matter. When you teach Devu the first subject, it will take him 3 hours per chapter. When you teach Devu the second subject, it will take him 2 hours per chapter. When you teach Devu the third subject, it will take him 1 hours per chapter. In total it takes 6 hours.

【题目大意】
Dove要学习n个课程,每个课程有一定的章节数。他可以按照任意的顺序学习这n门课程。一开始他学习一个章节的时间是x,但是每学完一个课程之后,他学习一个章节的时间就会减少1(最少是1)。
问Dove学完所有课程所需要花的最少时间。
【解法】
因为越早学的课程需要的时间越多,为了让总的时间最少,优先学习章节数较少的课程。所以按照章节数进行升序排序,然后依次学习即可。
【坑点】
注意答案会爆int
【AC代码】

#include 
#include 
#include 
#include 
#include 

using namespace std;

long long a[100010];

int main(){
    long long n, x;
    long long ans;
    while(scanf("%I64d%I64d", &n, &x) != EOF){
        ans = 0;
        for(int i = 0; i < n; i++){
            scanf("%I64d", &a[i]);
        }
        sort(a, a + n);
        for(int i = 0; i < n; i++){
            if(x == 1){
                ans += a[i];
            }
            else{
                ans += x * a[i];
                x--;
            }
        }
        printf("%I64d\n", ans);
    }

    return 0;
}

A. Queue on Bus Stop

It’s that time of the year when the Russians flood their countryside summer cottages (dachas) and the bus stop has a lot of people. People rarely go to the dacha on their own, it’s usually a group, so the people stand in queue by groups.

The bus stop queue has n groups of people. The i-th group from the beginning has ai people. Every 30 minutes an empty bus arrives at the bus stop, it can carry at most m people. Naturally, the people from the first group enter the bus first. Then go the people from the second group and so on. Note that the order of groups in the queue never changes. Moreover, if some group cannot fit all of its members into the current bus, it waits for the next bus together with other groups standing after it in the queue.

Your task is to determine how many buses is needed to transport all n groups to the dacha countryside.
Input

The first line contains two integers n and m (1 ≤ n, m ≤ 100). The next line contains n integers: a1, a2, …, an (1 ≤ ai ≤ m).
Output

Print a single integer — the number of buses that is needed to transport all n groups to the dacha countryside.
Examples
Input

4 3
2 3 2 1

Output

3

Input

3 4
1 2 1

Output

1

【题目大意】
有一个队伍在排队等公交。排队的人是一伙一伙的。他们只会上同一辆车,如果坐不下就等下一辆车。严格按照队伍的顺序上车。求问需要多少辆车才能把所有人都载走。
【解法】
按照队伍的顺序依次向后,能够上车就上车,不能够上车就等下一趟。
【AC代码】

#include 
#include 
#include 
#include 
#include 

using namespace std;

int a[110];

int main(){
    int n, m;
    while(scanf("%d%d", &n, &m) != EOF){
        for(int i = 0; i < n; i++){
            scanf("%d", &a[i]);
        }
        int ans = 0;
        int sum = 0;
        for(int i = 0; i < n; i++){
            sum += a[i];
            if(sum < m){
                continue;
            }
            else if(sum == m){
                sum = 0;
                ans ++;

            }
            else{
                sum = 0;
                ans ++;
                i --;
            }
        }
        if(sum != 0){
            ans++;
        }
        printf("%d\n", ans);

    }
    return 0;
}

Radar Installation

Description
Assume the coasting is an infinite straight line. Land is in one side of coasting, sea in the other. Each small island is a point locating in the sea side. And any radar installation, locating on the coasting, can only cover d distance, so an island in the sea can be covered by a radius installation, if the distance between them is at most d.

We use Cartesian coordinate system, defining the coasting is the x-axis. The sea side is above x-axis, and the land side below. Given the position of each island in the sea, and given the distance of the coverage of the radar installation, your task is to write a program to find the minimal number of radar installations to cover all the islands. Note that the position of an island is represented by its x-y coordinates.

Figure A Sample Input of Radar Installations

Input
The input consists of several test cases. The first line of each case contains two integers n (1<=n<=1000) and d, where n is the number of islands in the sea and d is the distance of coverage of the radar installation. This is followed by n lines each containing two integers representing the coordinate of the position of each island. Then a blank line follows to separate the cases.

The input is terminated by a line containing pair of zeros

Output
For each test case output one line consisting of the test case number followed by the minimal number of radar installations needed. “-1” installation means no solution for that case.

Sample Input

3 2
1 2
-3 1
2 1

1 2
0 2

0 0

Sample Output

Case 1: 2
Case 2: 1
【题目大意】
这题可以转化成贪心的经典问题,区间覆盖问题
【解法】
以小岛为圆心,以雷达范围为半径画圆,将小岛全部转化成在坐标轴上的区间,然后用解决区间覆盖的方法解决即可。
【AC代码】

#include 
#include 
#include 
#include 
#include 

using namespace std;

//struct Point{
//    int x, y;
//}P[1010];

struct range{
    double left, right;
    bool is_select;
}R[1010];

bool cmp(range a, range b){
    if(abs(a.right - b.right) < 0.000001){
        return a.left < b.left;
    }
    return a.right < b.right;
}

int main(){
    int n, d, a, b;
    int term = 0;
    while(scanf("%d%d", &n, &d) != EOF && (n && d)){
        term++;
        int ok = 1;
        for(int i = 0; i < n; i++){
            scanf("%d%d", &a, &b);
            if(ok == 0){
                continue;
            }
            if(b > d){
                ok = 0;
                printf("Case %d: -1\n", term);
            }
            else if(b <= d){
                ok = 1;
                R[i].left = a - sqrt(d * d - b * b);
                R[i].right = a + sqrt(d * d - b * b);
                R[i].is_select = 0;
            }
        }
        if(ok == 0){
            continue;
        }
        sort(R, R + n, cmp);
//        for(int i = 0; i < n; i++){
//            printf("(%lf, %lf)\n", R[i].left, R[i].right);
//        }
        int ans = 0;
        for(int i = 0; i < n; i++){
            if( R[i].is_select == 0 ){
                R[i].is_select = 1;
                ans ++;
                for(int j = i + 1; j < n; j++){
                    if( R[j].left <= R[i].right ){
                        R[j].is_select = 1;
                    }
                    else{
                        i = j - 1;
                        break;
                    }
                }
            }
        }
        printf("Case %d: %d\n", term, ans);
    }
    return 0;
}

ztr loves lucky numbers

Problem Description
ztr loves lucky numbers. Everybody knows that positive integers are lucky if their decimal representation doesn’t contain digits other than 4 and 7. For example, numbers 47, 744, 4 are lucky and 5, 17, 467 are not.

Lucky number is super lucky if it’s decimal representation contains equal amount of digits 4 and 7. For example, numbers 47, 7744, 474477 are super lucky and 4, 744, 467 are not.

One day ztr came across a positive integer n. Help him to find the least super lucky number which is not less than n.

Input
There are T(1≤n≤105) cases

For each cases:

The only line contains a positive integer n(1≤n≤1018). This number doesn’t have leading zeroes.

Output
For each cases
Output the answer

Sample Input

2
4500
47

Sample Output

4747
47

【题目大意】
只由4跟7两个数码组成且4跟7的出现的次数一样的数叫做幸运数。
给出一个数,问不小于这个数的第一个幸运数是多少。

【解法】
先搜索出给定范围内的所有幸运数。然后排序。二分查找。

【AC代码】

#include 
#include 
#include 
#include 
#include 

using namespace std;

long long a[270000];
int index;

void dfs(int x, int y, long long num){
    if(x == 0 && y == 0){
        a[index++] = num;
        return ;
    }
    if(x > 0){
        dfs(x - 1, y, num * 10 + 4);
    }
    if(y > 0){
        dfs(x, y - 1, num * 10 + 7);
    }
}

int main(){
    for(int i = 2; i <= 18; i += 2){
        dfs(i >> 1, i >> 1, 0);
    }
    sort(a, a + index);
//    for(int i = 0 ; i < 100; i++){
//        printf("%I64d\n", a[i]);
//    }
    int T;
    long long num;
    scanf("%d", &T);
    while(T--){
        scanf("%I64d", &num);
        if(num > 777777777444444444){
            printf("44444444447777777777\n");
        }
        else{
            printf("%I64d\n",  *lower_bound(a, a + index, num));
        }
    }

    return 0;
}

B. Wilbur and Array

Wilbur the pig is tinkering with arrays again. He has the array a1, a2, …, an initially consisting of n zeros. At one step, he can choose any index i and either add 1 to all elements ai, ai + 1, … , an or subtract 1 from all elements ai, ai + 1, …, an. His goal is to end up with the array b1, b2, …, bn.

Of course, Wilbur wants to achieve this goal in the minimum number of steps and asks you to compute this value.
Input

The first line of the input contains a single integer n (1 ≤ n ≤ 200 000) — the length of the array ai. Initially ai = 0 for every position i, so this array is not given in the input.

The second line of the input contains n integers b1, b2, …, bn ( - 109 ≤ bi ≤ 109).
Output

Print the minimum number of steps that Wilbur needs to make in order to achieve ai = bi for all i.
Examples
Input

5
1 2 3 4 5

Output

5

Input

4
1 2 2 1

Output

3

Note

In the first sample, Wilbur may successively choose indices 1, 2, 3, 4, and 5, and add 1 to corresponding suffixes.

In the second sample, Wilbur first chooses indices 1 and 2 and adds 1 to corresponding suffixes, then he chooses index 4 and subtract 1.

【题目大意】
有一串一开始全是0的数。每次可以选择一个位置p,执行两个操作中的一个:
1.p以后的每个数(包括p)全部加1
2.p以后的每个数(包括p)全部减1
另外给出一段序列。求问,从初始状态(全零)到目标状态(给定状态)至少需要多少步。

【解法】
因为每次操作都只影响后面的。所以按照顺序,依次改变成目标状态即可。

【AC代码】

#include 
#include 
#include 
#include 
#include 

using namespace std;

int a[200010];
int main(){
    int n;
    while(scanf("%d", &n) != EOF){
        long long ans = 0;
        for(int i = 1; i <= n; i++){
            scanf("%d", &a[i]);
            ans += abs(a[i] - a[i - 1]);
        }

        printf("%I64d\n", ans);

    }
    return 0;
}

你可能感兴趣的:(2016暑期集训)