Codeforces Round #339 (Div. 2) 解题报告

614A. Link/Cut Tree

                time limit per test2 seconds    memory limit per test256 megabytes

Programmer Rostislav got seriously interested in the Link/Cut Tree data structure, which is based on Splay trees. Specifically, he is now studying the expose procedure.

Unfortunately, Rostislav is unable to understand the definition of this procedure, so he decided to ask programmer Serezha to help him. Serezha agreed to help if Rostislav solves a simple task (and if he doesn’t, then why would he need Splay trees anyway?)

Given integers l, r and k, you need to print all powers of number k within range from l to r inclusive. However, Rostislav doesn’t want to spent time doing this, as he got interested in playing a network game called Agar with Gleb. Help him!

Input
The first line of the input contains three space-separated integers l, r and k (1 ≤ l ≤ r ≤ 1018, 2 ≤ k ≤ 109).

Output
Print all powers of number k, that lie within range from l to r in the increasing order. If there are no such numbers, print “-1” (without the quotes).

input
1 10 2
output
1 2 4 8

input
2 4 5
output
-1

Note
Note to the first sample: numbers 20=1,21=2,22=4,23=8 lie within the specified range. The number 24=16 is greater then 10, thus it shouldn’t be printed.

题目链接:cf-614A

题目大意:输出k的 ni=0 次方在[l,r]范围内的数字

题目思路:刚开始的做法是直接用pow,但是会爆long long,比如说k = 1e9的时候。所有后来采用了每次翻k倍,预先判断有没有超过r / k的范围。

以下是代码:

#include <vector>
#include <map>
#include <set>
#include <algorithm>
#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <string>
#include <cstring>
using namespace std;
int main(){
    long long l,r,k;
    cin >> l >> r >> k;
    int flag = 1;
    long long ret = 1;
    for (long long i = 0;; i++)
    {
        if (ret > r) break;
        if (ret >= l) printf("%I64d ",ret),flag = 0;
        if (ret > r / k) break;
        ret *= k;
    }
    if (flag) cout << -1 << endl;
    return 0;
}

614B-Gena’s Code

                time limit per test0.5 seconds      memory limit per test256 megabytes

It’s the year 4527 and the tanks game that we all know and love still exists. There also exists Great Gena’s code, written in 2016. The problem this code solves is: given the number of tanks that go into the battle from each country, find their product. If it is turns to be too large, then the servers might have not enough time to assign tanks into teams and the whole game will collapse!

There are exactly n distinct countries in the world and the i-th country added ai tanks to the game. As the developers of the game are perfectionists, the number of tanks from each country is beautiful. A beautiful number, according to the developers, is such number that its decimal representation consists only of digits ‘1’ and ‘0’, moreover it contains at most one digit ‘1’. However, due to complaints from players, some number of tanks of one country was removed from the game, hence the number of tanks of this country may not remain beautiful.

Your task is to write the program that solves exactly the same problem in order to verify Gena’s code correctness. Just in case.

Input
The first line of the input contains the number of countries n (1 ≤ n ≤ 100 000). The second line contains n non-negative integers ai without leading zeroes — the number of tanks of the i-th country.

It is guaranteed that the second line contains at least n - 1 beautiful numbers and the total length of all these number’s representations doesn’t exceed 100 000.

Output
Print a single number without leading zeroes — the product of the number of tanks presented by each country.

input
3
5 10 1
output
50

input
4
1 1 10 11
output
110

input
5
0 3 1 100 1
output
0

Note
In sample 1 numbers 10 and 1 are beautiful, number 5 is not not.

In sample 2 number 11 is not beautiful (contains two ‘1’s), all others are beautiful.

In sample 3 number 3 is not beautiful, all others are beautiful.

题目链接:cf-614B

题目大意:给出n个数字求相乘结果。美丽数字的定义为,最多只含有1个1,其余全为0.并且只有一个数字为不美丽数字。

题目思路:记录不美丽数字,其余数字记录0的个数加在后面就行了。因为其余数字只含有最多1个1。

注意:
1. 可能存在全是美丽数字的情况,这时候需要先输出1,再输出一串0
2. 可能存在0,这时候结果输出 0 即可。(无论什么数字和0相乘都是0)

以下是代码:

#include <vector>
#include <map>
#include <set>
#include <algorithm>
#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <string>
#include <cstring>
using namespace std;
int isbeauty(string s)
{
    int one = 0,zero = 0;
    for (int i = 0; i < s.size(); i++)
    {
        if (s[i] != '1' && s[i] != '0') return -1;  //本来返回0,但是需要考虑0的个数可能为0
        if (s[i] == '1') one++;
        if (one > 1) return -1;
        if (s[i] == '0') zero++;
    }
    return zero;  //返回0的个数
}
string num[100010];
int main(){
    int n;
    cin >> n;
    string ans;
    int zero = 0;
    int flag = 1;
    int ok = 0;
    for (int i = 0; i < n; i++)
    {
        string s;
        cin >> s;
        if (s == "0") flag = 0;
        int ret = isbeauty(s);
        if (ret == -1) ans = s,ok = 1;
        if (ret >= 0) zero += ret;
    }
    if (!ok) ans = "1";
    if (!flag) cout << 0 << endl;
    else
    {
        cout << ans;
        for (int i = 0; i < zero; i++) cout << 0;
        cout << endl;       
    }

    return 0;
}

614C-Peter and Snow Blower【几何】

                time limit per test2 seconds        memory limit per test256 megabytes

Peter got a new snow blower as a New Year present. Of course, Peter decided to try it immediately. After reading the instructions he realized that it does not work like regular snow blowing machines. In order to make it work, you need to tie it to some point that it does not cover, and then switch it on. As a result it will go along a circle around this point and will remove all the snow from its path.

Formally, we assume that Peter’s machine is a polygon on a plane. Then, after the machine is switched on, it will make a circle around the point to which Peter tied it (this point lies strictly outside the polygon). That is, each of the points lying within or on the border of the polygon will move along the circular trajectory, with the center of the circle at the point to which Peter tied his machine.

Peter decided to tie his car to point P and now he is wondering what is the area of ​​the region that will be cleared from snow. Help him.

Input
The first line of the input contains three integers — the number of vertices of the polygon n (), and coordinates of point P.

Each of the next n lines contains two integers — coordinates of the vertices of the polygon in the clockwise or counterclockwise order. It is guaranteed that no three consecutive vertices lie on a common straight line.

All the numbers in the input are integers that do not exceed 1 000 000 in their absolute value.

Output
Print a single real value number — the area of the region that will be cleared. Your answer will be considered correct if its absolute or relative error does not exceed 10 - 6.

Namely: let’s assume that your answer is a, and the answer of the jury is b. The checker program will consider your answer correct, if .

input
3 0 0
0 1
-1 2
1 2
output
12.566370614359172464

input
4 1 -1
0 0
1 2
2 0
1 1
output
21.991148575128551812

Note
In the first sample snow will be removed from that area:

题目链接:cf-614C

题目大意:给出圆心坐标和一个多边形的n个顶点坐标,问这个多边形绕圆心旋转所能形成的最大面积。

题目思路:根据note,我们知道肯定是一个圆环,所以只需要找到图形上到圆心的最远点和最近点即可。

                    最远点一定在点上,最近点可能在点上可能在边上

具体判断方法是:由于点的给出方法为顺时针或逆时针,所以只需要O(n)扫一遍环即可,利用余弦定理去判断形成的角是否为钝角,(即最近点是不是在给定的边上)如果是钝角的话那么则取两个端点的最小值,如果不是的话则利用海伦公式求高即可。

参考博客:这里

以下是代码:

#include <vector>
#include <map>
#include <set>
#include <algorithm>
#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <string>
#include <cstring>
using namespace std;
#define PI acos(-1.0)
#define EPS 1e-6
struct node
{
    double x,y;
}p[100010];
#define INF 999999999999999
double dist (node x1,node x2)
{
    return sqrt((x1.x - x2.x) * (x1.x - x2.x) + (x1.y - x2.y) * (x1.y - x2.y));
}
int main(){
    int n;
    node cer;
    cin >> n >> cer.x >> cer.y;
    double max_r = -1,min_r = INF; 
    for (int i = 0; i < n; i++)
    {
        cin >> p[i].x >> p[i].y;
        max_r = max(max_r,dist(cer,p[i]));
    }
    for (int i = 0; i < n; i++)
    {
        double a,b,c;
        if (i == n - 1)
        {
            a = dist(cer,p[i]);
            b = dist(cer,p[0]);
            c = dist(p[i],p[0]);
        }
        else
        {
            a = dist(cer,p[i]);
            b = dist(cer,p[i + 1]);
            c = dist(p[i],p[i + 1]);
        }
        if (a * a + c * c - b * b < 0 || b * b + c* c - a * a < 0)  //如果是钝角 
        {
            min_r = min(min_r,min(a, b));
        }
        else  //根据海伦公式求高 
        {
            double pp = (a + b + c) / 2;
            min_r = min(min_r, 2 * sqrt(pp * (pp - a) * (pp - b) * (pp - c)) / c);
        }
    }
    double s = ((max_r * max_r) - (min_r * min_r)) * PI;
    printf("%.16f\n",s);
    return 0;
}

614D. Skills

                time limit per test2 seconds        memory limit per test256 megabytes

Lesha plays the recently published new version of the legendary game hacknet. In this version character skill mechanism was introduced. Now, each player character has exactly n skills. Each skill is represented by a non-negative integer ai — the current skill level. All skills have the same maximum level A.

Along with the skills, global ranking of all players was added. Players are ranked according to the so-called Force. The Force of a player is the sum of the following values:

The number of skills that a character has perfected (i.e., such that ai = A), multiplied by coefficient cf.
The minimum skill level among all skills (min ai), multiplied by coefficient cm.
Now Lesha has m hacknetian currency units, which he is willing to spend. Each currency unit can increase the current level of any skill by 1 (if it’s not equal to A yet). Help him spend his money in order to achieve the maximum possible value of the Force.

Input
The first line of the input contains five space-separated integers n, A, cf, cm and m (1 ≤ n ≤ 100 000, 1 ≤ A ≤ 109, 0 ≤ cf, cm ≤ 1000, 0 ≤ m ≤ 1015).

The second line contains exactly n integers ai (0 ≤ ai ≤ A), separated by spaces, — the current levels of skills.

Output
On the first line print the maximum value of the Force that the character can achieve using no more than m currency units.

On the second line print n integers a’i (ai ≤ a’i ≤ A), skill levels which one must achieve in order to reach the specified value of the Force, while using no more than m currency units. Numbers should be separated by spaces.

input
3 5 10 1 5
1 3 1
output
12
2 5 2

input
3 5 10 1 339
1 3 1
output
35
5 5 5

Note
In the first test the optimal strategy is to increase the second skill to its maximum, and increase the two others by 1.

In the second test one should increase all skills to maximum.

题目链接:cf-614D

题目大意:n个科目,每个科目最高分为A,现在最多能提高m分。最后权值是达到A分的科目个数 * cf + 最低分 * cm。求提高单科分数之后,最后的权值最大是多少。并打印出方案。

题目思路:贪心,枚举 + 二分

以下是代码:

AC代码:

#include <bits/stdc++.h> 
using namespace std;
typedef long long ll;
#define PB push_back
#define UB upper_bound
#define LB lower_bound
#define MP make_pair
#define pii pair<int,int>
#define vi vector<int>
#define vii vector<vi>
#define mst(x,y) memset(x,y,sizeof(x))
#define fr(x) freopen(x,"r",stdin)
#define fw(x) freopen(x,"w",stdout)
#define sp system("pause")
#define INF 1e17
#define MAXN 100011
#define PI acos(-1.0)
#define eps 1e-10

bool cmp(pii a,pii b)
{
    return a.first < b.first;
}

bool cmpp(pii a,pii b)
{
    return a.second < b.second;
}

int main()
{
    ll n,a,cf,cm,m,sum[100005] = {0},mmid,ccnt,flag2;
    int pos;
    ll maxx = -1,flag = 0;
    pii f[100005];
    cin >> n >> a >> cf >> cm >> m;
    for(int i = 0;i < n;i++)
    {
        cin >> f[i].first;
        f[i].second = i;
    }
    sort(f,f + n,cmp);
    sum[0] = (ll)f[0].first;
    for(int i = 1;i < n;i++)
    {
        sum[i] = sum[i - 1] + (ll)f[i].first;
    }
    if(a * n - sum[n] <= m)
    {
        cout << n * cf + a * cm << endl;
        cout << a;
        for(int i = 1;i < n;i++)
            cout << " " << a;
        return 0;
    }
    for(int i = n;i >= 0;i--)
    {
        ll lef = m - (a * (n - i) - sum[n - 1] + (i == 0 ? 0 : sum[i - 1]));
        if(lef < 0)
            break;
        ll l = 0,r = a;
        while(l <= r)
        {
            ll mid = (l + r) >> 1;
            pii mids;
            mids.first = mid;
            pos = LB(f,f + i,mids) - f;
            if(mid * pos - sum[pos - 1] > lef)
                r = mid - 1;
            else
                l = mid + 1;
        }
        if((n - i) * cf + ((l + r) >> 1) * cm > maxx)
        {
            maxx = (n - i) * cf + ((l + r) >> 1) * cm;
            mmid = (l + r) >> 1;
            flag = i;flag2 = pos;
        }
    }
    for(int i = n - 1;i >= flag;i--)
        f[i].first = a;
    for(int i = 0;i <= flag2 - 1;i++)
            f[i].first = mmid;
    sort(f,f + n,cmpp);
    cout << maxx << endl;
    cout << f[0].first;
    for(int i = 1;i < n;i++)
        cout << " " << f[i].first;
}

待改代码:

#include <vector>
#include <map>
#include <set>
#include <algorithm>
#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <string>
#include <cstring>
using namespace std;
struct node
{
    int id;
    int value;
    bool operator < (const node& a) const {
        if (value != a.value) return value > a.value;  //先按照天数的先后顺序排序
    }
}num[100010];
bool cmp1 (node a, node b)
{
    return a.value < b.value;
}
bool cmp2 (node a,node b)
{
    return a.id < b.id;
}
int sum[100010];
int max_ans,max_a,mid_ans,flag1,flag2;
int main(){
    int n,a,cf,cm,m;
    cin >> n >> a >> cf >> cm >> m;
    for (int i = 1; i <= n; i++)
    {
        cin >> num[i].value;
        num[i].id = i;
    }
    sort(num + 1,num + n + 1,cmp1);
    sum[1] = num[1].value;
    for (int i = 2; i <= n; i++) sum[i] = sum[i - 1] + num[i].value; 

    if (m >= n * a - sum[n])
    {
        cout << n * cf  + a * cm<< endl;
        cout << a;
        for (int i = 2; i <= n; i++) cout << " " << a; 
    }
    else
    {
        for (int i = 0; i <= n; i++)  //后面i个达到最大值 
        {
            int cost = m - (i  * a - sum[n] + sum[n - i]);  //剩余 
            if (cost < 0) continue;
            int l = 0,r = a;
            int pos = 0;
            while(l <= r)
            {
                node mid;
                mid.value = (l + r) >> 1;
                pos = lower_bound(num + 1,num + n - i + 1,mid) - num;
                cout << "... " << pos  << " " << mid.value << endl; 
            // cout << mid.value * pos - sum[pos] << " " << cost << endl;
                if (mid.value * pos - sum[pos] > cost) r = mid.value - 1;
                else l = mid.value + 1;
            }
            cout << i << " " << i * cf + ((l + r) >> 1) * cm << endl;
            if (i * cf + ((l + r) >> 1) * cm > max_ans)
            {
                cout << i << " " << (l + r) / 2 << endl;
                max_ans = i * cf + ((l + r) >> 1) * cm;
            // max_a = n - i + 1;
                mid_ans = (l + r) >> 1; 
                flag1 = n - i,flag2 = pos;
            // max_i = pos;
            }
        }
        for (int i = 1; i <= flag2; i++) num[i].value = mid_ans;
        for (int i = flag1; i <= n; i++) num[i].value = a;
        sort(num + 1,num + n + 1,cmp2);
        cout << max_ans << endl;
        cout << num[1].value;
        for (int i = 2; i <= n; i++) cout << " " << num[i].value;
    }
    return 0;
}

你可能感兴趣的:(codeforces)