新生训练赛002

B.Is it beautiful?

You are given a permutation p=[p1,p2,…,pn] of integers from 1 to n. Let’s call the number m (1≤m≤n) beautiful, if there exists two indices l,r (1≤l≤r≤n), such that the numbers [pl,pl+1,…,pr] is a permutation of numbers 1,2,…,m.
For example, let p=[4,5,1,3,2,6]. In this case, the numbers 1,3,5,6 are beautiful and 2,4 are not. It is because:

  • if l=3 and r=3 we will have a permutation [1] for m=1;
  • if l=3 and r=5 we will have a permutation [1,3,2] for m=3;
  • if l=1 and r=5 we will have a permutation [4,5,1,3,2] for m=5;
  • if l=1 and r=6 we will have a permutation [4,5,1,3,2,6] for m=6;
  • it is impossible to take some l and r, such that [pl,pl+1,…,pr] is a permutation of numbers 1,2,…,m for m=2 and for m=4.

You are given a permutation p=[p1,p2,…,pn]. For all m (1≤m≤n) determine if it is a beautiful number or not.

Input

The first line contains the only integer t (1≤t≤1000) — the number of test cases in the input. The next lines contain the description of test cases.
The first line of a test case contains a number n (1≤n≤2⋅105) — the length of the given permutation p. The next line contains n integers p1,p2,…,pn (1≤pi≤n, all pi are different) — the given permutation p.
It is guaranteed, that the sum of n from all test cases in the input doesn’t exceed 2⋅105.

Output

Print t lines — the answers to test cases in the order they are given in the input.
The answer to a test case is the string of length n, there the i-th character is equal to 1 if i is a beautiful number and is equal to 0 if i is not a beautiful number.

Example

Input
3
6
4 5 1 3 2 6
5
5 3 1 2 4
4
1 4 3 2
Output
101011
11111
1001
Note
The first test case is described in the problem statement.
In the second test case all numbers from 1 to 5 are beautiful:

  • if l=3 and r=3 we will have a permutation [1] for m=1;
  • if l=3 and r=4 we will have a permutation [1,2] for m=2;
  • if l=2 and r=4 we will have a permutation [3,1,2] for m=3;
  • if l=2 and r=5 we will have a permutation [3,1,2,4] for m=4;
  • if l=1 and r=5 we will have a permutation [5,3,1,2,4] for m=5.

题解

单调栈的简单应用,我们认为在一个区间中最大的数是控制这个区间的,那么我们要满足题意,便是要找一个数,它控制的区间的长 = = 它的大小。
也就相当于,从左到右,除了它本身没有比它大的数,单调栈可以求出一个数,从它本身开始作为最大(最小)值向左(右)延伸的最大区间。
例如样例中4,5,1,3,2,6.
可以求出:

  • 4作为区间最大值,向左为本身,向右为本身
  • 5作为区间最大值,向左到4,向右到2
  • 1为本身
  • 3向左到1,向右到2
  • 2为本身
  • 6向左到4,向右为本身

我们将各自所能到达的最远距离记下来,只要保证距离小于该数即可。

#include <bits/stdc++.h>
const int MAXN = 1e6 + 1;
using namespace std;

long long n, q[MAXN], l[MAXN], r[MAXN], a[MAXN];
struct vec {
    int a;
    int i;
    bool operator<(vec x)
    {
        return a < x.a;
    }
} ti[MAXN];
long long read()
{
    int x = 0, f = 1;
    char c = getchar();
    while (c < '0' || c > '9') {
        if (c == '-')
            f = -1;
        c = getchar();
    }
    while (c >= '0' && c <= '9') {
        x = x * 10 + c - '0';
        c = getchar();
    }
    return x;
}
int main()
{
    int t;
    cin >> t;
    while (t--) {
        cin >> n;
        memset(ti, 0, sizeof(ti));
        int head = 1, tail = 0;
        for (int i = 1; i <= n; i++) {
            a[i] = read();
            while (tail >= head && a[i] > a[q[tail]]) //维持单调性,注意保存的是下标
                tail--;
            l[i] = tail < head ? 1 : q[tail] + 1; //如果它不是栈首,我们就认为它左边有矩形
            q[++tail] = i;
        }
        head = 1, tail = 0;
        for (int i = n; i > 0; i--) {
            while (tail >= head && a[i] > a[q[tail]])
                tail--;
            r[i] = tail < head ? n : q[tail] - 1;
            q[++tail] = i;
        }
        for (int i = 1; i <= n; i++) {
            ti[i].a = a[i];
            if (r[i] - l[i] + 1 >= a[i])
                ti[i].i = 1;
            else
                ti[i].i = 0;
        }
        sort(ti + 1, ti + n + 1);
        for (int i = 1; i <= n; i++)
            cout << ti[i].i;
        cout << endl;
    }
    return 0;
}

C.Juicer

Farmer John’s cows have taken a side job designing interesting punch-bowl designs. The designs are created as follows:

  • A flat board of size W cm x H cm is procured (3 <= W <= 300, 3 <= H <= 300)
  • On every 1 cm x 1 cm square of the board, a 1 cm x 1 cm block is placed. This block has some integer height B (1 <= B <= 1,000,000,000)

The blocks are all glued together carefully so that punch will not drain through them. They are glued so well, in fact, that the corner blocks really don’t matter!

FJ’s cows can never figure out, however, just how much punch their bowl designs will hold. Presuming the bowl is freestanding (i.e., no special walls around the bowl), calculate how much juice the bowl can hold. Some juice bowls, of course, leak out all the juice on the edges and will hold 0.

Input

  • Line 1: Two space-separated integers, W and H

  • Lines 2…H+1: Line i+1 contains row i of bowl heights: W space-separated integers each of which represents the height B of a square in the bowl. The first integer is the height of column 1, the second integers is the height of column 2, and so on.

Output

  • Line 1: A single integer that is the number of cc’s the described bowl will hold.

Example

Sample Input
4 5
5 8 7 7
5 2 1 5
7 1 7 1
8 9 6 9
9 8 9 9
Sample Output
12
Hint
OUTPUT DETAILS:
Fill-up the two squares of height 1 to height 5, for 4 cc for each square. Fill the square of height 2 to height 5, for 3 cc of joice. Fill the square of height 6 to height 7 for 1 cc of juice. 2 × 4 + 3 + 1 = 12 2\times 4 + 3 + 1 = 12 .

题解

诚如大佬所说,搜索这玩意想刁难人真的太五花八门了。
根据题面,我们知道,我们要求出这个碗,能称下多少水。

  • 首先碗边必然是不能溢出的。
  • 如果碗内有四个边比碗边还高的,就不用担心碗边。

于是,我们就可以从碗边开始搜索。

  • 比碗边低的,我们计算差值,并补齐。
  • 比碗边高的,我们就把它算入一个新的碗边,存下来。

取碗边时,为了防止溢出,自然是要从最低的点入手,故使用优先队列存储。

#include <cmath>
#include <iostream>
#include <queue>
using namespace std;
const int MAXN = 50000 + 10;
const double pi = acos(-1.0);
const double inf = 1e100;
const double eps = 1e-12;

struct node {
    int x, y;
    int h;
    friend bool operator<(node p, node _p)
    {
        return p.h > _p.h;
    }
};
int mp[400][400], v[400][400];
int dx[] = { 1, 0, -1, 0 }, dy[] = { 0, 1, 0, -1 };
priority_queue<node> q;
int main()
{
    int n, m;
    cin >> m >> n;
    for (int i = 1; i <= n; i++)
        for (int j = 1; j <= m; j++)
            cin >> mp[i][j];
    for (int i = 1; i <= n; i++) {
        v[i][1] = 1;
        v[i][m] = 1;
        q.push(node{ i, 1, mp[i][1] });
        q.push(node{ i, m, mp[i][m] });
    }
    for (int i = 1; i <= m; i++) {
        v[1][i] = 1;
        v[n][i] = 1;
        q.push(node{ n, i, mp[n][i] });
        q.push(node{ 1, i, mp[1][i] });
    }
    int res = 0;
    while (!q.empty()) {
        node p = q.top();
        q.pop();
        for (int i = 0; i < 4; i++) {
            int x = p.x + dx[i], y = p.y + dy[i];
            if (!v[x][y] && x > 1 && x < n && y > 1 && y < m) {
                //cout << x << ' ' << y << ' ' << mp[x][y] << endl;
                if (mp[x][y] >= p.h) {
                    q.push(node{ x, y, mp[x][y] });
                } else {
                    res += p.h - mp[x][y];
                    mp[x][y] = p.h;
                    q.push(node{ x, y, mp[x][y] });
                }
                v[x][y] = 1;
            }
        }
    }
    cout << res << endl;
    return 0;
}

E.由你来决定怎么颁奖

So the Beautiful Regional Contest (BeRC) has come to an end! n students took part in the contest. The final standings are already known: the participant in the i-th place solved pi problems. Since the participants are primarily sorted by the number of solved problems, then p1≥p2≥⋯≥pn.
Help the jury distribute the gold, silver and bronze medals. Let their numbers be g, s and b, respectively. Here is a list of requirements from the rules, which all must be satisfied:
for each of the three types of medals, at least one medal must be awarded (that is, g>0, s>0 and b>0);
the number of gold medals must be strictly less than the number of silver and the number of bronze (that is, g<s and g<b, but there are no requirements between s and b);
each gold medalist must solve strictly more problems than any awarded with a silver medal;
each silver medalist must solve strictly more problems than any awarded a bronze medal;
each bronze medalist must solve strictly more problems than any participant not awarded a medal;
the total number of medalists g+s+b should not exceed half of all participants (for example, if n=21, then you can award a maximum of 10 participants, and if n=26, then you can award a maximum of 13 participants).
The jury wants to reward with medals the total maximal number participants (i.e. to maximize g+s+b) so that all of the items listed above are fulfilled. Help the jury find such a way to award medals.

Input

The first line of the input contains an integer t (1≤t≤10000) — the number of test cases in the input. Then t test cases follow.
The first line of a test case contains an integer n (1≤n≤4⋅ 1 0 5 10^5 ) — the number of BeRC participants. The second line of a test case contains integers p1,p2,…,pn (0≤pi≤ 1 0 6 10^6 ), where pi is equal to the number of problems solved by the i-th participant from the final standings. The values pi are sorted in non-increasing order, i.e. p1≥p2≥⋯≥pn.
The sum of n over all test cases in the input does not exceed 4 × 1 0 5 4\times 10^5 .

Output

Print t lines, the j-th line should contain the answer to the j-th test case.

The answer consists of three non-negative integers g,s,b.

Print g=s=b=0 if there is no way to reward participants with medals so that all requirements from the statement are satisfied at the same time.
Otherwise, print three positive numbers g,s,b — the possible number of gold, silver and bronze medals, respectively. The sum of g+s+b should be the maximum possible. If there are several answers, print any of them.

Example

Input
5
12
5 4 4 3 2 2 1 1 1 1 1 1
4
4 3 2 1
1
1000000
20
20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1
32
64 64 63 58 58 58 58 58 37 37 37 37 34 34 28 28 28 28 28 28 24 24 19 17 17 17 17 16 16 16 16 11
Output
1 2 3
0 0 0
0 0 0
2 5 3
2 6 6

Note

In the first test case, it is possible to reward 1 gold, 2 silver and 3 bronze medals. In this case, the participant solved 5 tasks will be rewarded with the gold medal, participants solved 4 tasks will be rewarded with silver medals, participants solved 2 or 3 tasks will be rewarded with bronze medals. Participants solved exactly 1 task won’t be rewarded. It’s easy to see, that in this case, all conditions are satisfied and it is possible to reward participants in this way. It is impossible to give more than 6 medals because the number of medals should not exceed half of the number of participants. The answer 1, 3, 2 is also correct in this test case.
In the second and third test cases, it is impossible to reward medals, because at least one medal of each type should be given, but the number of medals should not exceed half of the number of participants.

题解

要求颁发金银铜奖,金<银,且金<铜,但却对银和铜的关系没有要求
其次要求金解题数>银解题数>铜。
自然想到把相同解题数的人当作一个块来处理。并将小于n/2的人数取出来,方便判断。
于是,我们考虑,要让g+s+b最大,人数是固定的, g + s + b < = s u m & & g < s & & g < b g+s+b<=sum{\&\&}g<s{\&\&}g<b
那么我们在保证题目要求下,g无论取什么,保证s了,那么剩下的都是b
方便来做,自然是把g放的人数最小,s次小,剩下全扔给b。
这样就能取出最大的g+s+b。

#include <bits/stdc++.h>
using namespace std;
const int MAXN = 4e5 + 10;
const double pi = acos(-1.0);
const double inf = 1e100;
const double eps = 1e-12;

int a[MAXN];
struct vec {
    int d;
    int s;
} v[MAXN];
int main()
{
    int t;
    cin >> t;
    while (t--) {
        memset(v, 0, sizeof(v));
        int n, tot = 0;
        cin >> n;
        cin >> a[1];
        v[++tot].d = a[1];
        v[tot].s = 1;
        for (int i = 2; i <= n; i++) {
            scanf("%d", &a[i]); //cin >> a[i];
            if (v[tot].d != a[i])
                v[++tot].d = a[i];
            v[tot].s++;
        }
        int cnt = 0, sum = 0;
        for (int i = 1; i <= tot; i++) {
            sum += v[i].s;
            if (sum > n / 2) {
                cnt = i - 1;
                sum -= v[i].s;
                break;
            }
        }
        int x = v[1].s, y = 0, z = 0;
        if (x * 3 >= sum)
            x = 0;
        else {
            for (int i = 2; i <= cnt; i++) {
                y += v[i].s;
                if (y > x && sum - y - x > x) {
                    z = sum - y - x;
                    break;
                }
            }
        }
        if (z == 0)
            cout << 0 << ' ' << 0 << ' ' << 0 << endl;
        else
            cout << x << ' ' << y << ' ' << z << endl;
    }
    return 0;
}

F.XorXor

Alex has a sequence S which contains n elements, let’s define f(i, j) denoting the xor sum of Si, Si+1, …, Sj. Now Alex wants to know the value of f(1, 1) xor f(1, 2) xor … xor f(1, n) xor f(2, 2) xor f(2, 3) xor … xor f(2, n) xor … xor f(n, n).

Input

Input starts with an integer T denoting the number of test case.
For each test case, first line contains an integer n (1 <= n <= 100000).
Next line contains n integers Si(1 <= Si <= 100000).

Output

For each test case. print the value of
f(1, 1) xor f(1, 2) xor … xor f(1, n) xor f(2, 2) xor f(2, 3) xor … xor f(2, n) xor … xor f(n, n).

Example

Sample Input
1
3
1 3 2
Sample Output
3
Hint

题解

定义一个函数 f ( i , j ) = S i S i + 1 . . . S j f(i,j)=S_i {\oplus}S_{i+1}{\oplus}...{\oplus}S_j
要求 f ( 1 , 1 ) f ( 1 , 2 ) . . . . f ( 1 , n ) f ( 2 , 2 ) f ( 2 , 3 ) . . . . f ( 2 , n ) . . . . f ( n , n ) f(1,1)\oplus f(1,2)\oplus ....\oplus f(1,n)\oplus f(2,2)\oplus f(2,3)\oplus ....\oplus f(2,n)\oplus ....\oplus f(n,n)
很简单的二进制计算题,虽然我脑抽找了半天规律。
a a = 0 a\oplus a=0 ,然后算一下每一项异或的次数,判断奇偶,奇数次就异或起来,输入完事

#include <cmath>
#include <iostream>
#include <queue>
using namespace std;
const int MAXN = 1e5 + 10;
const double pi = acos(-1.0);
const double inf = 1e100;
const double eps = 1e-12;

int main()
{
    int t;
    cin >> t;
    while (t--) {
        long long n, sum = 0;
        scanf("%lld", &n);
        for (int i = 1; i <= n; i++) {
            long long cnt = i * (n - i + 1), a;
            scanf("%lld", &a);
            if (cnt % 2 == 1)
                sum ^= a;
        }
        cout << sum << endl;
    }
    return 0;
}

J.新年快乐

Frog Wa has many frogs, so he can hear GuaGuaGua every day. But one day a flappy bird ate his frogs, so Frog Wa decided to build a fence to protect his precious frogs. Frog Wa told you four points (x, 0), (x, y), (z, 0), (z, t) which represent for the vertex of the fence. he want to know the area of the fence, can you tell him?

Input

The input consist of four integers x, y, z and t. 0 <= x, y, z, t <= 10000, x < z and y < t.

Output

For each test case, print the area, numbers should accurate to one decimal places.

Example

Sample Input
1 1 2 2
0 2 6 6
0 0 2 10
Sample Output
1.5
24.0
10.0
Hint

题解

简单几何签到题。
非常仁慈的直角梯形,套公式即可。
当然,存下四个点,当成多边形套一下叉积就完事了。

#include <cmath>
#include <iostream>
using namespace std;
const int MAXN = 50000 + 10;
const double pi = acos(-1.0);
const double inf = 1e100;
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;
    }
};
double duobianxingmianji(point po[], int num) //多边形面积
{
    double ans = 0;
    po[0] = po[num];
    for (int i = 0; i < num; i++)
        ans += (po[i] ^ po[i + 1]);
    ans = fabs(ans) * 0.5;
    return ans;
}
point p[MAXN];
int main()
{
    int x, y, z, t;
    while (cin >> x >> y >> z >> t) {
        p[1] = point(x, 0);
        p[2] = point(z, 0);
        p[3] = point(z, t);
        p[4] = point(x, y);
        printf("%.1f\n", duobianxingmianji(p, 4));
    }
    return 0;
}
发布了62 篇原创文章 · 获赞 13 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/UnKfrozen/article/details/103941153
今日推荐