凉心的比赛(一)

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:

  1. swap any pair of adjacent characters (for example, “101” “110”);
  2. 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).
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.

题解

签到题,很明显,0不能在1前.
然后就是1000…就阔以了

#pragma comment(linker, "/STACK:102400000,102400000")
#include <bits/stdc++.h>
using namespace std;
const int MAXN = 1e5 + 10;
const double pi = acos(-1.0);
const int inf = __LONG_MAX__;
const long long INF = LLONG_MAX;
const double eps = 1e-12;

int main()
{
    int len;
    string s;
    cin >> len >> s;
    int zero = 0, one = 0;
    for (int i = 0; i < len; i++)
        if (s[i] == '1')
            one++;
        else
            zero++;
    if (one)
        cout << 1;
    for (int i = 1; i <= zero; i++)
        cout << 0;
    return 0;
}

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.

题解

很巧妙地思维题,我们考虑两个线段如果相互包含的条件是什么?
l i > l j & & r i < r j l_i>l_j\&\&r_i<r_j
那么我们按照 l l 从小到大排序,我们可以保证, l i > l i + 1 l_i>l_{i+1} .
然后再按照 l l 相同情况下,将 r r 从大到小排序.
然后我们每次存下来判断过的线段的最大 r r ,那么我们的 M A X _ r MAX\_r 只要大于当前的 r i r_i ,就可以得到,包含的关系.

#pragma comment(linker, "/STACK:102400000,102400000")
#include <bits/stdc++.h>
using namespace std;
const int MAXN = 4e5 + 10;
const double pi = acos(-1.0);
const int inf = __LONG_MAX__;
const long long INF = LLONG_MAX;
const double eps = 1e-12;

struct segment {
    int l, r, pos;
    bool operator<(segment L)
    {
        return l == L.l ? r > L.r : l < L.l;
    }
} s[MAXN];
int main()
{
    int n;
    cin >> n;
    for (int i = 0; i < n; i++) {
        cin >> s[i].l >> s[i].r;
        s[i].pos = i + 1;
    }
    sort(s, s + n);
    int maxr = s[0].r, a = 0, b = -2;
    for (int i = 1; i < n; i++) {
        if (s[i].r > maxr) {
            a = i;
            maxr = s[i].r;
        } else {
            b = i;
            break;
        }
    }
    if (b == -2)
        cout << -1 << ' ' << -1 << endl;
    else
        cout << s[b].pos << ' ' << s[a].pos << endl;
    return 0;
}

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:
1

题解

规律题,根据所给提示,我们可以画出任意一张图的路线.
然后,总结下规律,就解决了

#pragma comment(linker, "/STACK:102400000,102400000")
#include <bits/stdc++.h>
using namespace std;
const int MAXN = 4e5 + 10;
const double pi = acos(-1.0);
const int inf = __LONG_MAX__;
const long long INF = LLONG_MAX;
const double eps = 1e-12;

int main()
{
    long long n, m, k;
    cin >> n >> m >> k;
    k++;
    if (k <= n)
        cout << k << ' ' << 1 << endl;
    else {
        k -= n;
        k--;
        long long a = k / (2 * (m - 1));
        n = n - 2 * a;
        long long b = k % (2 * (m - 1));
        if (b >= m - 1) {
            n--;
            m = 2 * m - 2 - b;
        } else
            m = b + 1;
        cout << n << ' ' << m + 1 << endl;
    }
    return 0;
}

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.

题解

首先,规律:

  • 平均的对每一个 h p × 2 hp\times 2 远不如单独对一个 h p × 2 a hp\times 2^a

由此,我们就有了初步的解决方式,枚举每一个 h p i hp_i 对其 × 2 a \times 2^a ,并存下来进行比较得最大值.
当然 n 2 n^2 必然超时.
于是,我们要进行优化.
首先,如果不进行咒语,那么 a n s = d m g i ans=\sum{dmg_i}
如果仅进行 b b 操作,那么要求必然是 h p i > d m g i hp_i>dmg_i ,设 0 0 t e m p temp 为止符合该不等式.
那么 c n t = i = 0 t e m p 1 h p i cnt=\sum_{i=0}^{temp-1} {hp_i}
但是为了方便计算,我们令 c n t = i = 0 t e m p 1 ( h p i d m g i ) cnt=\sum_{i=0}^{temp-1} {(hp_i-dmg_i)}
这是因为 c n t + a n s = i = 0 t e m p 1 h p i + i = t e m p n 1 d m g i cnt+ans=\sum_{i=0}^{temp-1} {hp_i}+\sum_{i=temp}^{n-1}dmg_i
那么我们考虑,当我们对 0 n 1 0\dots n-1 中的一位 h p i × 2 a , d m g i = h p i hp_i\times 2^a,dmg_i=hp_i ,在这里,我们令新的 d m g i dmg_i s u m sum .
这里的运算不仅消耗了全部的 a a ,还多消耗了一次 b b .
于是,我们需要判断:

  • 如果, i < t e m p i<temp ,那么我们只需要 c n t + a n s h p i + s u m cnt+ans-hp_i+sum
  • 如果 i t e m p & & b > t e m p i\ge temp\&\&b>temp ,那么我们只需要 c n t + a n s d m g i + s u m cnt+ans-dmg_i+sum
  • 如果 i t e m p & & b = t e m p i\ge temp\&\&b=temp ,那么我们需要 c n t + a n s + d m g t e m p 1 h p t e m p 1 + s u m cnt+ans+dmg_{temp-1}-hp_{temp-1}+sum

综上,写成程序即可,需要理解,可自行画图

#pragma comment(linker, "/STACK:102400000,102400000")
#include <bits/stdc++.h>
using namespace std;
const int MAXN = 4e5 + 10;
const double pi = acos(-1.0);
const int inf = __LONG_MAX__;
const long long INF = LLONG_MAX;
const double eps = 1e-12;
 
typedef long long ll;
struct node {
    long long dmg, hp;
    bool operator<(node x)
    {
        return ((hp - dmg) == (x.hp - x.dmg) ? dmg > x.dmg : (hp - dmg) > (x.hp - x.dmg));
    }
} p[MAXN];
int main()
{
    ll n, a, b, ans = 0;
    cin >> n >> a >> b;
    for (int i = 0; i < n; i++) {
        cin >> p[i].hp >> p[i].dmg;
        ans += p[i].dmg;
    }
    if (b == 0) {
        cout << ans << endl;
        return 0;
    }
    sort(p, p + n);
    ll cnt = 0, temp = b;
    for (int i = 0; i < b; i++) {
        if (p[i].hp < p[i].dmg) {
            temp = i;
            break;
        }
        cnt += p[i].hp - p[i].dmg;
    }
    long long maxx = 0;
    for (int i = 0; i < n; i++) {
        long long sum = (1 << a) * p[i].hp;
        if (i < temp)
            sum += cnt + ans - p[i].hp;
        else if (b > temp)
            sum += cnt + ans - p[i].dmg;
        else
            sum += cnt + ans - p[temp - 1].hp - p[i].dmg + p[temp - 1].dmg;
        maxx = max(maxx, sum);
    }
    cout << max(maxx, ans) << endl;
    return 0;
}

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

题解

简单几何签到题

  • 对于一个点 P P ,如果点在圆外,那么题目所给的圆为最大圆
  • 对于点 P P 在圆内,如果点 P P 和圆心 O O 重叠,则在圆上任意一点 M M 与圆心 O O 形成直径,所得圆为最大圆
  • 对于点 P P 在圆内,且不与圆心 O O 重叠,则连接圆心 O O 和点 P P , P O \overrightarrow{PO} 方向延长 P O PO ,与圆所交点 M M ,则 P M PM 为最大圆的直径
#pragma comment(linker, "/STACK:102400000,102400000")
#include <bits/stdc++.h>
using namespace std;
const int MAXN = 4e5 + 10;
const double pi = acos(-1.0);
const int inf = __LONG_MAX__;
const long long INF = LLONG_MAX;
const double eps = 1e-12;
 
typedef struct point vec;
struct point { //点的基本数据结构
    double x, y;
    double poe;
    point(double _x = 0, double _y = 0)
        : x(_x)
        , y(_y)
    {
    }
    double len() //模长
    {
        return sqrt(x * x + y * y);
    }
    vec chuizhi()
    {
        return vec(-y, x);
    }
    double operator*(const point& i_T) const //点积
    {
        return x * i_T.x + y * i_T.y;
    }
    double operator^(const point& i_T) const //叉积
    {
        return x * i_T.y - y * i_T.x;
    }
    point operator*(double u) const
    {
        return point(x * u, y * u);
    }
    bool operator==(const point& i_T) const
    {
        return fabs(x - i_T.x) < eps && fabs(y - i_T.y) < eps;
    }
    point operator/(double u) const
    {
        return point(x / u, y / u);
    }
    point operator+(const point& i_T)
    {
        return point(x + i_T.x, y + i_T.y);
    }
    point operator-(const point& i_T)
    {
        return point(x - i_T.x, y - i_T.y);
    }
    friend bool operator<(point a, point b)
    {
        return fabs(a.y - b.y) < eps ? a.x < b.x : a.y < b.y;
    }
    void atn2()
    {
        poe = atan2(y, x);
    }
    friend ostream& operator<<(ostream& out, point& a)
    {
        //cout << a.x << ' ' << a.y;
        printf("%.8f %.8f", a.x, a.y);
        return out;
    }
    friend istream& operator>>(istream& in, point& a)
    {
        scanf("%lf%lf", &a.x, &a.y);
        return in;
    }
};
struct cirles {
    point o;
    double r;
    cirles(point _o = point(), double _r = 0.0)
        : r(_r)
        , o(_o)
    {
    }
    point Point(double t) //圆上任意一点
    {
        return point(o.x + r * cos(t), o.y + r * sin(t));
    }
    friend istream& operator>>(istream& in, cirles& a)
    {
        in >> a.o >> a.r;
        return in;
    }
    friend ostream& operator<<(ostream& out, cirles& a)
    {
        out << a.o << ' ';
        printf("%.8f", a.r);
        return out;
    }
};
typedef struct Line Segment; //线段Segment
struct Line { //直线
    point a, b;
    double poe;
    Line(point _a = point(), point _b = point())
        : a(_a)
        , b(_b)
    {
    }
    double len()
    {
        return (a - b).len();
    }
    friend istream& operator>>(istream& in, Line& a)
    {
        cin >> a.a >> a.b;
        return in;
    }
    friend ostream& operator<<(ostream& out, Line& a)
    {
        out << a.a << ' ' << a.b;
        return out;
    }
    void atn2()
    {
        poe = atan2(b.y - a.y, b.x - a.x);
    }
};
int bijiao(double x, double y)
{
    if (fabs(x - y) < eps)
        return 0;
    if (x > y)
        return 1;
    return -1;
}
point zhixian_zhixian_jiaodian(Line l1, Line l2) //两直线交点
{
    double t = ((l1.a.x - l2.a.x) * (l2.a.y - l2.b.y) - (l1.a.y - l2.a.y) * (l2.a.x - l2.b.x)) / ((l1.a.x - l1.b.x) * (l2.a.y - l2.b.y) - (l1.a.y - l1.b.y) * (l2.a.x - l2.b.x));
    return l1.a + (l1.b - l1.a) * t;
}
pair<point, point> zhixian_yuan_jiaodian(cirles c, Line l) //直线与圆相交的交点
{
    point p = c.o;
    double t;
    p.x += l.a.y - l.b.y;
    p.y += l.b.x - l.a.x;
    p = zhixian_zhixian_jiaodian(Line(p, c.o), l);
    t = sqrt(c.r * c.r - (p - c.o).len() * (p - c.o).len()) / (l.a - l.b).len();
    return make_pair<point, point>(p + (l.b - l.a) * t, p - (l.b - l.a) * t);
}
int main()
{
    cirles c;
    point p, k;
    cin >> c.r >> c.o >> p;
    if (bijiao((p - c.o).len(), c.r) != -1) {
        cout << c << endl;
        return 0;
    } else if (p == c.o) {
        k = c.Point(1);
    } else {
        pair<point, point> pa = zhixian_yuan_jiaodian(c, Line(p, c.o));
        double len1 = (pa.first - p).len(), len2 = (pa.second - p).len();
        k = (bijiao(len1, len2) != -1 ? pa.first : pa.second);
    }
    cirles _c = cirles((k + p) / 2, (p - k).len() / 2);
    cout << _c << endl;
    return 0;
}
发布了62 篇原创文章 · 获赞 13 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/UnKfrozen/article/details/103950183