凉心的比赛(一)补题和题解

在这里插入图片描述

题目链接

前置知识

神圣之灵


这张牌可以让一个随从的生命值翻倍

心灵之火

在这里插入图片描述
让一个随从的攻击力等于生命值

A - 最小的二进制数 CodeForces - 976A

题目

String can be called correct if it consists of characters “0” and “1” and there are no redundant leading zeroes. Here are some examples: “0”, “10”, “1001”.

You are given a correct string s.

You can perform two different operations on this string:

swap any pair of adjacent characters (for example, “101” “110”);
replace “11” with “1” (for example, “110” “10”).
Let val(s) be such a number that s is its binary representation.

Correct string a is less than some other correct string b iff val(a) < val(b).

扫描二维码关注公众号,回复: 8675054 查看本文章

Your task is to find the minimum correct string that you can obtain from the given one using the operations described above. You can use these operations any number of times in any order (or even use no operations at all).

Input
The first line contains integer number n (1 ≤ n ≤ 100) — the length of string s.

The second line contains the string s consisting of characters “0” and “1”. It is guaranteed that the string s is correct.

Output
Print one string — the minimum correct string that you can obtain from the given one.

Examples
Input
4
1001
Output
100
Input
1
1
Output
1
Note
In the first example you can obtain the answer by the following sequence of operations: “1001” “1010” “1100” “100”.

In the second example you can’t obtain smaller answer no matter what operations you use.

题意

给你一个串只包含10,可以任意删除其中的1或者0 问可以组成的最小二进制数是多少

思路

如果有1的话就留一个1 剩下补0 如果没有1的话 最小就是0

代码

#include <bits/stdc++.h>
using namespace std;
int main()
{
    int n;
    scanf("%d",&n);
    string s;
    cin>>s;
    int num=0,num1=0;
    for(int i=0;i<n;i++)
    {
        if(s[i]=='1')
        num1++;
        if(s[i]=='0')
        num++;
    }
    if(num==0)
    {
        if(num1!=0)
        cout<<"1";
        else
        cout<<0;
    }
    else
    {
        if(num1!=0)
        {
            cout<<1;
            for(int i=1;i<=num;i++)
            cout<<0;
        }
        else
        {
            cout<<0;
        }
    }
}

B - 线段的包含关系 CodeForces - 976C

题目

You are given a sequence a1, a2, …, an of one-dimensional segments numbered 1 through n. Your task is to find two distinct indices i and j such that segment ai lies within segment aj.

Segment [l1, r1] lies within segment [l2, r2] iff l1 ≥ l2 and r1 ≤ r2.

Print indices i and j. If there are multiple answers, print any of them. If no answer exists, print -1 -1.

Input
The first line contains one integer n (1 ≤ n ≤ 3·105) — the number of segments.

Each of the next n lines contains two integers li and ri (1 ≤ li ≤ ri ≤ 109) — the i-th segment.

Output
Print two distinct indices i and j such that segment ai lies within segment aj. If there are multiple answers, print any of them. If no answer exists, print -1 -1.

Examples
Input
5
1 10
2 9
3 9
2 3
2 9
Output
2 1
Input
3
1 5
2 6
6 20
Output
-1 -1
Note
In the first example the following pairs are considered correct:

(2, 1), (3, 1), (4, 1), (5, 1) — not even touching borders;
(3, 2), (4, 2), (3, 5), (4, 5) — touch one border;
(5, 2), (2, 5) — match exactly.

题意

给你n个线段,如果有两个线段有包含关系,输出这两个线段,任意一组都可以,只需要输出一组。

思路

按照L从小到大排序,如果L相同的话就按照长度排,长的排在前面。
排序以后设一个maxx记录当前线段R最大值,由于按照L排过序了,所以后面的线段的L都大于等于前面的L,所以只要是R小于前面最大的一个,那么最大的那一个一定包含着当前的这个找的时候不要忘记记录最大值和当前最大值的id。

代码

#include <bits/stdc++.h>
using namespace std;
const int maxn = 500000+100;
class seg
{
    public:
        int l,r,id;
}a[maxn];

bool cmp(seg a,seg b)
{
    if(a.l==b.l)
    return a.r>b.r;
    return a.l<b.l;
}

int main()
{
    int n;
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
    scanf("%d%d",&a[i].l,&a[i].r),a[i].id=i;
    sort(a+1,a+1+n,cmp);
    int maxx = a[1].r,ans1 = 1;
    for(int i=2;i<=n;i++)
    {
        // printf("%d %d\n",a[i].r,maxx);
        if(a[i].r<=maxx)
        return printf("%d %d\n",a[i].id,a[ans1].id),0;
        else
        {
            if(a[i].r>maxx)
            {
                maxx=a[i].r;
                ans1=i;
            }
        }
    }
    printf("-1 -1\n");
}

C - 地下城还有劳拉 CodeForces - 976B

题目

You might have heard about the next game in Lara Croft series coming out this year. You also might have watched its trailer. Though you definitely missed the main idea about its plot, so let me lift the veil of secrecy.

Lara is going to explore yet another dangerous dungeon. Game designers decided to use good old 2D environment. The dungeon can be represented as a rectangle matrix of n rows and m columns. Cell (x, y) is the cell in the x-th row in the y-th column. Lara can move between the neighbouring by side cells in all four directions.

Moreover, she has even chosen the path for herself to avoid all the traps. She enters the dungeon in cell (1, 1), that is top left corner of the matrix. Then she goes down all the way to cell (n, 1) — the bottom left corner. Then she starts moving in the snake fashion — all the way to the right, one cell up, then to the left to the cell in 2-nd column, one cell up. She moves until she runs out of non-visited cells. n and m given are such that she always end up in cell (1, 2).

Lara has already moved to a neighbouring cell k times. Can you determine her current position?

Input
The only line contains three integers n, m and k (2 ≤ n, m ≤ 109, n is always even, 0 ≤ k < n·m). Note that k doesn’t fit into 32-bit integer type!

Output
Print the cell (the row and the column where the cell is situated) where Lara ends up after she moves k times.

Examples
Input
4 3 0
Output
1 1
Input
4 3 11
Output
1 2
Input
4 3 7
Output
3 2
Note
Here is her path on matrix 4 by 3:

在这里插入图片描述

题意

给你一个n*m的迷宫,一共可以走k步,刚开始只能往下走然后到了最后一一排往右走 ,然后是往左,如图所示。问你最后走到的地方是第几排第几列

思路

画图找规律,把不同的k代入发现第几行比较好求 直接就是y=n-(k-1)/m;
第几列就把前面走到最后一行的k步数先减去,然后根据奇偶不同算列,当k-1/m&1的时候求(k-1)/m的原因是如果直接用k的话一行里面的结果不同,无法使用规律如果k能被剩下的m整除的话x就等于2 否则就等于x=m+2-k%m; 剩下的那个也一样。这个规律画画图还是比较好找的

代码

#include <bits/stdc++.h>
using namespace std;
int main()
{
    long long n,m,k;
    scanf("%lld%lld%lld",&n,&m,&k);
    if(k<=n-1)
    {
        if(k==0)
        printf("1 1\n");
        else
        printf("%lld 1\n",k+1);
    }
    else
    {
        k-=n-1;
        m--;
        long long x,y;
        if(((k-1)/m)&1)
        {
            if(k%m!=0)
            x=m+2-k%m;
            else
            x=2;
        }
        else
        {
            if(k%m!=0)
            x=k%m+1;
            else
            x=m+1;
        }
        y=n-(k-1)/m;
        printf("%lld %lld\n",y,x);
    }
}

D - 心火牧日常计算 CodeForces - 976E

题目

Recently Max has got himself into popular CCG “BrainStone”. As “BrainStone” is a pretty intellectual game, Max has to solve numerous hard problems during the gameplay. Here is one of them:

Max owns n creatures, i-th of them can be described with two numbers — its health hpi and its damage dmgi. Max also has two types of spells in stock:

Doubles health of the creature (hpi := hpi·2);
Assigns value of health of the creature to its damage (dmgi := hpi).
Spell of first type can be used no more than a times in total, of the second type — no more than b times in total. Spell can be used on a certain creature multiple times. Spells can be used in arbitrary order. It isn’t necessary to use all the spells.

Max is really busy preparing for his final exams, so he asks you to determine what is the maximal total damage of all creatures he can achieve if he uses spells in most optimal way.

Input
The first line contains three integers n, a, b (1 ≤ n ≤ 2·105, 0 ≤ a ≤ 20, 0 ≤ b ≤ 2·105) — the number of creatures, spells of the first type and spells of the second type, respectively.

The i-th of the next n lines contain two number hpi and dmgi (1 ≤ hpi, dmgi ≤ 109) — description of the i-th creature.

Output
Print single integer — maximum total damage creatures can deal.

Examples
Input
2 1 1
10 15
6 1
Output
27
Input
3 0 3
10 8
7 11
5 2
Output
26
Note
In the first example Max should use the spell of the first type on the second creature, then the spell of the second type on the same creature. Then total damage will be equal to 15 + 6·2 = 27.

In the second example Max should use the spell of the second type on the first creature, then the spell of the second type on the third creature. Total damage will be equal to 10 + 11 + 5 = 26.

题意

我们有了前置技能以后看这题就比较简单了,有两张牧师的卡的操作,最多操作a次一操作,b次二操作。问最后得到的伤害总和是多少(这套otk感觉已经过时了2333)

思路

先按照用b操作然后a操作最优的方式排序让hp-dam大的排前面然后先计算不用操作的时候最大值是多少,证明出把每个一操作都加在一个人身上最优,之后对于前b个枚举每一个使用a次一操作然后使用一次b操作的最大值,最后由于这样不是最优(我也不知道为什么这样为什么还不行)就把最后一个使用ab操作的随从b操作取消,把这个b操作换到后面的随从使用(只用神圣之灵让hp翻倍不用心火的话只是hp增加了伤害并没有增加)枚举每一个使用a的最大值 ,最后求出来的就是最大值。
具体细节代码里有

代码

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 200000+1000;

class node
{
    public:
        ll hp,dam,sub;
}t[maxn];
bool cmp(node a,node b)
{
    return a.sub>b.sub;
}
int main()
{
    ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
    int n,a,b;
    cin>>n>>a>>b;
    for(int i=1;i<=n;i++)
    {
        cin>>t[i].hp>>t[i].dam;
        t[i].sub = t[i].hp - t[i].dam;
    }
    sort(t+1,t+1+n,cmp);
    ll sum=0;
    for(int i=1;i<=b;i++)
    sum+=max(t[i].hp,t[i].dam);
    for(int i=b+1;i<=n;i++)
    sum+=t[i].dam;
    ll ans=sum;
    for(int i=1;i<=b;i++)
    ans = max(ans,sum-max(t[i].hp,t[i].dam)+(t[i].hp<<a));//之前统计的时候默认了使用b操作,
    //所以这时候使用a操作需要减去之前统计的
    sum = sum - max(t[b].hp,t[b].dam)+t[b].dam;//可能前b个不是最优,就把第b个人取消使用a操作
    if(b)
    for(int i=b+1;i<=n;i++)
    ans = max(ans,sum-t[i].dam+(t[i].hp<<a));//之前统计的就是dam 所以减去dam 按照操作a来计算,
    //取消了b的b操作,才能使用a操作
    // 因为到最后如果一直神圣之灵的话没有放心火最后的伤害不会增加,只是hp增加了而已
    cout<<ans;
}

E - 法法在分配工作 CodeForces - 935A

题目

Fafa owns a company that works on huge projects. There are n employees in Fafa’s company. Whenever the company has a new project to start working on, Fafa has to divide the tasks of this project among all the employees.

Fafa finds doing this every time is very tiring for him. So, he decided to choose the best l employees in his company as team leaders. Whenever there is a new project, Fafa will divide the tasks among only the team leaders and each team leader will be responsible of some positive number of employees to give them the tasks. To make this process fair for the team leaders, each one of them should be responsible for the same number of employees. Moreover, every employee, who is not a team leader, has to be under the responsibility of exactly one team leader, and no team leader is responsible for another team leader.

Given the number of employees n, find in how many ways Fafa could choose the number of team leaders l in such a way that it is possible to divide employees between them evenly.

Input
The input consists of a single line containing a positive integer n (2 ≤ n ≤ 105) — the number of employees in Fafa’s company.

Output
Print a single integer representing the answer to the problem.

Examples
Input
2
Output
1
Input
10
Output
3
Note
In the second sample Fafa has 3 ways:

choose only 1 employee as a team leader with 9 employees under his responsibility.
choose 2 employees as team leaders with 4 employees under the responsibility of each of them.
choose 5 employees as team leaders with 1 employee under the responsibility of each of them.

题意

分老板和员工,问可以平局分配员工的方案数有多少

思路

枚举一下就ok

代码

#include <bits/stdc++.h>
using namespace std;
int main()
{
    int n,ans=0;
    scanf("%d",&n);
    for(int i=1;i<=n-1;i++)
    if((n-i)%i==0)
    {
        // cout<<n-i<<" "<<i<<endl;
        ans++;
    }
    printf("%d\n",ans);
}

F - 法法要穿过大门 CodeForces - 935B

题目

Two neighboring kingdoms decided to build a wall between them with some gates to enable the citizens to go from one kingdom to another. Each time a citizen passes through a gate, he has to pay one silver coin.

The world can be represented by the first quadrant of a plane and the wall is built along the identity line (i.e. the line with the equation x = y). Any point below the wall belongs to the first kingdom while any point above the wall belongs to the second kingdom. There is a gate at any integer point on the line (i.e. at points (0, 0), (1, 1), (2, 2), …). The wall and the gates do not belong to any of the kingdoms.

Fafa is at the gate at position (0, 0) and he wants to walk around in the two kingdoms. He knows the sequence S of moves he will do. This sequence is a string where each character represents a move. The two possible moves Fafa will do are ‘U’ (move one step up, from (x, y) to (x, y + 1)) and ‘R’ (move one step right, from (x, y) to (x + 1, y)).

Fafa wants to know the number of silver coins he needs to pay to walk around the two kingdoms following the sequence S. Note that if Fafa visits a gate without moving from one kingdom to another, he pays no silver coins. Also assume that he doesn’t pay at the gate at point (0, 0), i. e. he is initially on the side he needs.

Input
The first line of the input contains single integer n (1 ≤ n ≤ 105) — the number of moves in the walking sequence.

The second line contains a string S of length n consisting of the characters ‘U’ and ‘R’ describing the required moves. Fafa will follow the sequence S in order from left to right.

Output
On a single line, print one integer representing the number of silver coins Fafa needs to pay at the gates to follow the sequence S.

Examples
Input
1
U
Output
0
Input
6
RURUUR
Output
1
Input
7
URRRUUU
Output
2
Note
The figure below describes the third sample. The red arrows represent the sequence of moves Fafa will follow. The green gates represent the gates at which Fafa have to pay silver coins.
在这里插入图片描述

题意

fafa只能往上和往右走,问过程中穿过大门几次(正好站在大门上不算)大门是y=x这条线

思路

穿过大门只有两种情况
1 连着往右走两下,第一下到大门上,第二下往右走出去
2 连着往上走两下,第一下到大门上,第二下往上走出去

代码

#include <bits/stdc++.h>
using namespace std;
int main()
{
    int n;
    scanf("%d",&n);
    string s;
    cin>>s;
    int x=0,y=0,ans=0;
    for(int i=0;i<n-1;i++)
    {
        if(s[i]=='U')
        y++;
        else if(s[i]=='R')
        x++;
        if(x==y)
        {
            if(s[i]=='U')
            {
                if(s[i+1]=='U')
                ans++;
                else
                continue;
            }
            else if(s[i]=='R')
            {
                if(s[i+1]=='R')
                ans++;
                else
                continue;
            }
        }
    }
    printf("%d\n",ans);
}

G - 法法非法是朋友 CodeForces - 935C

题目

Fifa and Fafa are sharing a flat. Fifa loves video games and wants to download a new soccer game. Unfortunately, Fafa heavily uses the internet which consumes the quota. Fifa can access the internet through his Wi-Fi access point. This access point can be accessed within a range of r meters (this range can be chosen by Fifa) from its position. Fifa must put the access point inside the flat which has a circular shape of radius R. Fifa wants to minimize the area that is not covered by the access point inside the flat without letting Fafa or anyone outside the flat to get access to the internet.

The world is represented as an infinite 2D plane. The flat is centered at (x1, y1) and has radius R and Fafa’s laptop is located at (x2, y2), not necessarily inside the flat. Find the position and the radius chosen by Fifa for his access point which minimizes the uncovered area.

Input
The single line of the input contains 5 space-separated integers R, x1, y1, x2, y2 (1 ≤ R ≤ 105, |x1|, |y1|, |x2|, |y2| ≤ 105).

Output
Print three space-separated numbers xap, yap, r where (xap, yap) is the position which Fifa chose for the access point and r is the radius of its range.

Your answer will be considered correct if the radius does not differ from optimal more than 10 - 6 absolutely or relatively, and also the radius you printed can be changed by no more than 10 - 6 (absolutely or relatively) in such a way that all points outside the flat and Fafa’s laptop position are outside circle of the access point range.

Examples
Input
5 3 3 1 1
Output
3.7677669529663684 3.7677669529663684 3.914213562373095
Input
10 5 5 5 15
Output
5.0 5.0 10.0

题意

给定R和两个点,第一个点是圆的圆心,第二个点是给定的点,让求的是在圆里面取圆,让第二个点不在圆里面。求出要求圆的圆心和半径

思路

分三种情况讨论
1 点在圆外:要取的圆就是给定的圆
2 点在圆内且和圆心重合:此时在圆内随便找一个半径为R/2的内切圆即可
3 点在圆内且不和圆心重合:先求一下半径等于(R+d)/2; d是圆心到点的距离,然后根据相似三角形来求出要求圆的坐标,具体如下图所示:

在这里插入图片描述

代码

#include <bits/stdc++.h>
using namespace std;
double dis(double x1,double y1,double x2,double y2)
{
    return sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));
}
int main()
{
    double R,x1,x2,y1,y2;
    scanf("%lf%lf%lf%lf%lf",&R,&x1,&y1,&x2,&y2);
    if(x1==x2 && y1==y2)
    return printf("%.15lf %.15lf %.15lf",x1+R/2,y1,R/2),0;
    else
    {
        double d = dis(x1,y1,x2,y2);
        if(d>=R)
        return printf("%.15lf %.15lf %.15lf",x1,y1,R),0;
        else
        {
            double r = (R+d)/2;
            double ansy = y2+((y1-y2)/d)*r;
            double ansx = x2+((x1-x2)/d)*r;
            return printf("%.15lf %.15lf %.15lf",ansx,ansy,r),0;
        }
    }
}
发布了77 篇原创文章 · 获赞 61 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/weixin_43537190/article/details/104022265
今日推荐