The 19th Zhejiang Provincial Collegiate Programming Contest

时间:2022-09-13 08:13:05

第一次体验省赛,加油!

A.JB Loves Math

JB is good at Math, so he thinks all the math problems in the world are easy.

But one day, he meets a math problem which he can't solve, so he asks you to help him.

JB will give you two numbers a and b, and you should then choose a positive odd number x and a positive even number y. You can let a add x or let a minus y in one operation. You should change a into b in the minimal number of operations. Note that you are not allowed to change the value of x and y.

Input

In the first line, there is one integer T

(1T105), denoting the number of test cases.

For each test case, there is one line containing two numbers a

and b (1a,b106), denotes the number given by JB.

Output

For each test case, print one number, denoting the minimal number of operations you need to change a into b.

Example

Input

2
3 6
5 3

Output

1
1

这道题目使用打表就可以完成

要把a变成b,可以增加奇数,或者减少偶数,求最少的操作次数。

分以下5种情况

  1. a与b相等,0次
  2. a小于b,并且(b-a)为奇数,那么1次(增加b-a即可)
  3. a小于b,并且(b-a)为偶数,需要2次(增加两次\(\frac{b-a}{2}\)
    错误!
    因为\(\frac{b-a}{2}\)不一定是奇数!!。
    如果不是奇数的话,就要增加两个相同的奇数,然后减去一个偶数才可以达到。
  4. a大于b,并且(a-b)为偶数,那么直接减(a-b)
  5. a大于b,并且(a-b)为奇数,那么增加一,再减去(a-b+1)
    证明:
    增加一次不可以,增加两次有构造方案,所以是增加两次。

在写代码的时候一定要注意可读性,不然容易寄

#include <bits/stdc++.h>
using namespace std;
int T;
int main()
{
    cin >> T;
    while(T--)
    {
        int ans = 0;
        int a, b;
        scanf("%d%d", &a, &b);
        if(a == b) ans = 0;
        else if(a < b)
        {
            int d = b-a;
            if(d&1) ans = 1;
            else
            {
                if((d/2)&1) ans = 2;
                else ans = 3;
            }
        }
        else{
            int d = a-b;
            if(d&1) ans = 2;
            else ans = 1;
        }
        printf("%d\n", ans);
    }
    return 0;
}

B.JB Loves Comma

JB is the most famous ICPC world finalist. His favorite problem in ICPC world final is a problem which asks him to add some commas in a string.

Now, JB wants to share happiness with adding comma with you, so he asks you to add a comma after each substring “cjb” in a string S he gives you.

Input

The only line contains a string S (1 ≤ |S| ≤ 105), contains only lowercase English letters.

Output

One string, denotes the result after adding commas.

Examples

input 1

pbpbppb

output 1

pbpbppb

input 2

cjbismyson

output 2

cjb,ismyson

这道题目也是一个水题,由于仅仅比较三个字符,所以并没有必要采用KMP,直接比就行了。

#include <bits/stdc++.h>
using namespace std;
#define N 100020
char s[N];
int main()
{
    scanf("%s", s+1);
    int len = strlen(s+1);
    for(int i = 1; i <= 2; i++) putchar(s[i]);
    for(int i = 3; i <= len; i++)
    {
        putchar(s[i]);
        if(s[i-2] == 'c' && s[i-1] == 'j' && s[i] == 'b')
            putchar(',');

    }

    return 0;
}

C. JB Wants to Earn Big Money

JB has always wanted to make a lot of money, so recently he is addicted to stocks.

The trading rules of the stock market are as follows. Suppose there are n people who want to buy some shares while m people who want to sell some shares. Everyone will give a price.

The system will determine a final price x. For the people who want to buy some shares, if the price he gives is not lower than x, he will join the transaction. For the people who want to sell some shares, if the price he gives is not higher than x, he will join the transaction.

Now, JB gives you the price given by the people and the final price x. He wants you to tell him the number of people who can join the transaction.

Input

The first line contains three numbers n,m and x (1n,m,x105), denoting the number of two types of people and the final price determined by the system.

The second line contains n numbers a1,a2,,an (1ai105), denoting the price given by the people who want to buy some shares.

The third line contains m numbers b1,b2,,bm (1bi105), denoting the price given by the people who want to sell some shares.

Output

One number, denotes the number of people who can join the transaction.

Input

5 5 3
1 2 3 4 5
1 2 3 4 5

Output

6

这一道题目就是一个大水题!

#include <bits/stdc++.h>
using namespace std;
int n, m, k;

int main()
{
    scanf("%d%d%d", &n, &m, &k);
    int buf;
    int ans = 0;
    for(int i = 1; i <= n; i++)
    {
        scanf("%d", &buf);
        if(k <= buf) ans++;
    }
    for(int i = 1; i <= m; i++)
    {
        scanf("%d", &buf);
        if(k >= buf) ans++;
    }
    cout << ans;
    return 0;
}

G. Easy Glide

Grammy is playing a boring racing game named Easy Gliding. The game's
main content is to reach the destination as fast as possible by walking
or gliding(滑行). The fastest player wins.

Each player controls a character on a two-dimensional plane. A character can walk at any moment with a speed of V1.

Especially, when a character touches a gliding point, he/she can glide with a speed of \(V_2\) for the following 3 seconds. It is guaranteed that V1<V2.

Now Grammy locates at point S and she knows the coordinates(坐标) of all the gliding points p1,p2,…,pn. The goal is to reach point T as fast as possible. Could you tell her the minimum time she has to spend to reach point T?

Input

The first line contains one integer n (1n1000), denoting(表示) the number of gliding points.

The following n lines describe the gliding points. The i-th line contains two integers xi,yi (−1000000≤xi,yi≤1000000), representing the coordinates of the i-th gliding point pi.

The next line contains four integers,Sx,Sy,Tx,Ty(1000000Sx,Sy,Tx,Ty1000000), representing the coordinates of S and T.

The next line contains two integers V1,V2 (1V1<V21000000), representing the speed of walking and gliding.

Output

Output the minimum time Grammy has to spend to reach point T

in one line. Your answer will be considered correct if its absolute or relative error does not exceed \(10^{-6}\)

Examples

InputCopy

2
2 1
0 3
0 0 4 0
10 11

OutputCopy

0.400000000000

InputCopy

2
2 1
-2 0
0 0 4 0
1 2

OutputCopy

3.354101966250

InputCopy

2
2 1
-2 0
0 0 4 0
1 10000

OutputCopy

2.000600000000

如果要是不看题解,感觉还是比较难,但是看了题解以后,就觉简单了。

注意题目中的说法:小人可以从任意方向进行移动,所以从一点移动到另一点的时间就是\(\frac{两点之间的欧几里得距离}{速度}\)

现在进行分析:

从起点到重点,有以下几种情况:

  1. 不经过加速点,直接到达重点
  2. 经过几个特定的加速点,最终到达重点

如果不经过加速点,那么肯定是两点之间线段最短。

而如果是经过加速点的话,设经过的加速点的序列是\(a_1, a_2, a_{..}\)由贪心策略,从起点到加速点,从一个加速点到达另一个加速点,从加速点再到终点,肯定走的是直线距离(这样的话,在局部使用了贪心,从而使得求解问题成为了一种可能)

#include <bits/stdc++.h>
using namespace std;
#define N 1020
int n;
struct {
    double x, y;
}a[N];
/*
    1 is s;
    2-n+1 is point
    n+2 is t
*/
int head[N], ver[N*N], nxt[N*N], tot;
double v1, v2;
double edge[N*N];
priority_queue< pair<double, int>, vector<pair<double, int>>, greater<pair<double, int>> >q;
bool v[N];
double d[N];
double dist(int x, int y)
{
    double dx = a[x].x - a[y].x;
    double dy = a[x].y - a[y].y;
    return sqrt(dx*dx+dy*dy);
}
inline void add(int x, int y, double z)
{
    ver[++tot] = y;
    edge[tot] = z;
    nxt[tot] = head[x];
    head[x] = tot;
}
void djs()
{
    fill(d, d+N, 1e10);
    d[1] = 0;
    q.push({d[1], 1});
    while(!q.empty())
    {
            // cout << "djs";
        int x = q.top().second;
        q.pop();
        if(v[x]) continue;
        v[x] = true;
        for(int i = head[x]; i; i = nxt[i])
        {
            int y = ver[i];
            if(d[y] > d[x] + edge[i])
            {
                d[y] = d[x] + edge[i];
                q.push({d[y], y});
            }
        }
    }
}
int main()
{
    tot = 1;
    scanf("%d", &n);
    for(int i = 2; i <= n+1; i++){
        scanf("%lf%lf", &a[i].x, &a[i].y);
    }
    cin >> a[1].x >> a[1].y >> a[n+2].x >> a[n+2].y;
    n += 2;//修改一下,便于解决
    cin >> v1 >> v2;
    for(int i = 2; i <= n; i++)
    {
        add(1, i, dist(1, i) / v1);
    }
    for(int i = 2; i <= n; i++)
    {
        for(int j = 2; j <= n; j++)
        {
            if(i == j) continue;
            double d = dist(i, j);
            double len = 3 * v2;
            if(len >= d){
                add(i, j, d/v2);
            }
            else {
                add(i, j, 3+(d-len)/v1);
            }
        }
    }
    djs();
    printf("%.10lf", d[n]);
    return 0;
}

I. Barbecue

Putata and Budada are playing a new game. In the beginning, Putata has a
note with a string consists of lowercase letters on it. In each round,the player who has the note must rip off a character from the beginning or the end of the note, then pass it to the other player. If at any moment, the string on the note is a palindrome, then the player who has the note loses. Notice that both before or after the player ripping off a character from the note, the player is considered to have the note. A string s1s2sn of length n is considered to be a palindrome if for all integers i from 1 to n, si=sni+1.

However, when Putata found the note, he found that someone have played on this note before. Since both Putata and Budada are clever and will always
choose the best way to make themselves win, they wonder who will win the game, and they ask you for help. Formally, you are given a string of length n and you have to answer q queries, each query is described by two integers l and r, which means you have to determine who will win if Putata and Budada play the game described above on string slsl+1sr .

Input

The first line contains two integers n,q (1n,q1000000), denoting the length of the string and the number of queries.

The second line contains a string s of length n, consisting of lowercase English letters.

Each of the following q lines contains two integers l and r (1lrn), describing a query.

Output

For each query, print a single line. If Putata wins the game in one query, output "Putata" (without quotes). Otherwise output "Budada".

Example

InputCopy

7 3
potatop
1 3
3 5
1 6

OutputCopy

Putata
Budada
Budada

BUG出现在了字符串哈希中的p数组的p[0]项没有初始化为1,从而导致在中秋佳节卡了半个小时!

思路:

The 19th Zhejiang Provincial Collegiate Programming Contest

        #include <bits/stdc++.h>
        using namespace std;
        #define N 1000010
        unsigned long long order[N];
        unsigned long long reorder[N], p[N];
        char a[N];
        int n, T;
     
        int main()
        {
            scanf("%d%d", &n, &T);
            scanf("%s", a+1);
            p[0] = 1;
            for(int i = 1; i <= n; i++)
                p[i] = p[i-1]*131;
            for(int i = 1; i <= n; i++)
            {
                order[i] = order[i-1] * 131 + a[i] - 'a' + 1;
            }
            for(int i = n; i >= 1; i--)
            {
                reorder[i] = reorder[i+1] * 131 + a[i] - 'a' + 1;
            }
            for(int _ = 1; _ <= T; _++)
            {
                int l, r;
                scanf("%d%d", &l, &r);
                if(order[r] - order[l-1] * p[r-l+1] == reorder[l] - reorder[r+1]*p[r-l+1])
                {
                    puts("Budada");
                }
                // else if(order[r] - order[l] * p[r-l] == reorder[l+1] - reorder[r+1]*p[r-l] &&
                //         order[r-1] - order[l-1] * p[r-l] == reorder[l] - reorder[r]*p[r-l]
                // )
                // {
                //     puts("Budada");
                // }
                else{
                    if((r-l+1)&1 == 1)
                    {
                        puts("Putata");
                    }
                    else
                    {
                        puts("Budada");
                    }
                }
            }
            return 0;
        }


L. Candy Machine

JB loves candy very much.

One day, he finds a candy machine with N candies in it.

After reading the instructions of the machine, he knows that he can choose a subset(子集) of the N candies. Each candy has a sweet value. After JB chooses the subset, suppose the average sweet value of the chosen candies is X, all the candies with sweet value strictly larger than X will belong to JB. After JB makes the choice, the machine will disappear, so JB only has one opportunity to make a choice.

JB doesn't care how sweet the candies are, so he just wants to make a
choice to maximize the number of candies he will get. JB has been fascinated by candy and can't think, so he needs you to help him.

Input

The first line contains one integer N (1N106), denoting the number of candies in the machine.

The second line contains N integers a1,a2,,aN (1ai109), denoting the sweet values of the candies.

Output

One integer, denoting the maximum number of candies JB can get.

Example

InputCopy

5
1 2 3 4 5

OutputCopy

2

题目大意:

给定一个集合,要求在这一个集合中选择一个子集,设子集中元素的平均值是arv,要求求解子集中大于arv糖果的数目的最大值

这一道题目其实有一个很巧妙的思想:

因为随着数据的增加,删除,平均数是变着的,所以对于这一道题目就会显得捉摸不定。

我考虑一种最坏情况,假设平均数不大于K,那么小于K的所有值一定要选择(贪心,选的越多,就可以容纳大于K的数的个数越多)。对于大于K的数字,仅仅选择比K大一点点的数字(贪心,为了选择数目最多)。选择的最多的数目就是:

选取尽可能多的比K大一点点的,使得整体的平均值小于K的数字。

按照这样理解,那么最优的答案一定是选择的一个前缀。这样的话,遍历前缀,就可以得到答案。时间复杂度:\(O(nlogn)\)

最优的集合一定是原来的集合排好序之后的前缀(另一种证明):

假设所选的集合不连续,那么有:

The 19th Zhejiang Provincial Collegiate Programming Contest

代码一遍过,我还是那么强大

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define N 1000020
ll a[N];
ll n;
ll sum[N];
int main()
{
    ll ans = 0;
    cin >> n;
    for(int i = 1; i <= n; i++)
    {
        scanf("%lld", a+i);
    }
    sort(a+1, a+1+n);
    for(int i = 1; i <= n; i++)
    {
        sum[i] = sum[i-1] + a[i];
    }
    for(ll i = 1; i <= n; i++)
    {
        ll l = 1, r = n;
        while(l < r)
        {
            ll mid = (l+r)/2;
            if(a[mid]*i > sum[i]) r = mid;//大于平均值
            else l = mid + 1;
        }
        ans = max(ans, i - l + 1);
    }
    cout << ans;
    return 0;
}

M. BpbBppbpBB

Grammy has learned how to engrave stamps recently. She engraved two types of special stamps, type C has a capital letter "B" on it, and type S has a small letter "b" or a small letter "p" on it. The shapes and sizes of the stamps are illustrated in the following picture.

The 19th Zhejiang Provincial Collegiate Programming Contest

Grammy stamped these letters (with rotations) on a grid paper without
overlapping, the letters can only be pressed at the piece of paper if it lies totally inside the piece of paper. However, Grammy forgot how many times she used each type of stamps. Please count the letters and helpher to remember them.

The black part of the stamps may be adjacent but may not overlap.

Note that the stamps can be rotated to a multiple of 90 degrees.

Input

The first line consists of two integers n,m (1n,m1000), representing the size of the paper.

In the following n lines, each line consists of m characters, representing the current state of the paper. "#" stands for a black square and "." stands for a white square.

Output

Output two integers, denoting the number of type C stamps and the number of type S stamps, respectively.

Examples

InputCopy

10 17
#################
#################
#################
####..#####..####
###....###....###
###....###....###
####..#####..####
#################
#################
#################

OutputCopy

1 0

InputCopy

14 11
.##########
.##########
.##########
.####..####
.###....###
.###....###
.####..####
.##########
.##########
.##########
.###.......
.###.......
.###.......
.###.......

OutputCopy

0 1

InputCopy

20 14
.##########...
.##########...
.##########...
.####..####...
.###....###...
.###....###...
.####..####...
.##########...
.##########...
.##########...
.#############
.#############
.#############
.#######..####
....###....###
....###....###
....####..####
##############
##############
##############

OutputCopy

0 2

题目描述:

有两种形式的贴纸(中间有孔)粘在一张纸上(不可以重叠,贴纸没有超出纸的部分),求两种类型的贴纸各有多少个?

思路:找到所有的贴纸的中间的空白位置(这样形状的空白位置只有可能是贴纸的中间,不可能是其他边缘造成的),然后暴力枚举,当发现有两个空距离是C type的距离,就把这两个孔判断为C type的(两个贴纸相邻等其他情况中,两个孔的距离一定比C type中的两个孔的距离近)。

    #include <bits/stdc++.h>
    using namespace std;
    #define N 1005
    int n, m;
    char a[N][N];
    int dx[] = {0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3};
    int dy[] = {0, 1, -1, 0, 1, 2, -1, 0, 1, 2, 0, 1};
    vector<pair<int, int> > vec;
    bool judge(int i, int j)
    {
        if(i-1 < 1 || i+4 > n || j-2 < 1 || j+3 > m) return false;
        for(int _ = 0; _ < 12; _++)
        {
            int x = i+dx[_], y = j+dy[_];
            if(a[x][y] != '.')
            {
                return false;
            }
        }
        int cnt = 0;
        for(int row = i-1; row <= i+4; row++)
        {
            for(int col = j-2; col <= j+3; col++)
            {
               if(a[row][col] == '.') cnt++;
            }
        }
        if(cnt == 12) return true;
        else return false;
    }
    int main()
    {
        scanf("%d%d", &n, &m);
        for(int i = 1; i <= n; i++) scanf("%s", a[i] + 1);
        for(int i = 1; i <= n; i++)
        {
            for(int j = 1; j <= m; j++)
            {
                if(a[i][j] == '.')
                {
                    if(judge(i, j)) {
                        vec.push_back(make_pair(i, j));
                        // printf("(%d, %d)\n", i, j);
                        // fflush(stdout);
                    }
                }
            }
        }
        int cnt = 0;
        for(int i = 0; i < vec.size(); i++)
        {
            for(int j = i+1; j < vec.size(); j++)
            {
                int x1 = vec[i].first;
                int x2 = vec[j].first;
                int y1 = vec[i].second;
                int y2 = vec[j].second;
                if((abs(x1-x2)==7 && y1 == y2) || (abs(y1-y2) == 7 && x1 == x2))
                    cnt++;
            }
        }
        printf("%d %d", cnt, vec.size() - cnt*2);
        // for(int i = 0; i < vec.size(); i++)
        // {
        //     printf("(%d, %d)\n", vec[i].first, vec[i].second);
        // }
        return 0;
    }