第二次训练赛总结(二分)

第一题:A - 二分(经典题)
Farmer John has built a new long barn, with N (2 <= N <= 100,000) stalls. The stalls are located along a straight line at positions x1,…,xN (0 <= xi <= 1,000,000,000).

His C (2 <= C <= N) cows don’t like this barn layout and become aggressive towards each other once put into a stall. To prevent the cows from hurting each other, FJ want to assign the cows to the stalls, such that the minimum distance between any two of them is as large as possible. What is the largest minimum distance?
Input

  • Line 1: Two space-separated integers: N and C

  • Lines 2…N+1: Line i+1 contains an integer stall location, xi
    Output

  • Line 1: One integer: the largest minimum distance
    Sample Input
    5 3
    1
    2
    8
    4
    9
    Sample Output
    3
    Hint
    OUTPUT DETAILS:

FJ can put his 3 cows in the stalls at positions 1, 4 and 8, resulting in a minimum distance of 3.

Huge input data,scanf is recommended.
**思考:**经典二分题,牛分蓬,求最近两头牛的最大距离。像这样问的基本都是二分,二分求最大套路也就和本代码一样,主要是judge位置各有不同给,也同时是关键。因为之前写过所以很快就做完了,但是自己心里却很着急。
代码:

#include
#include
using namespace std;
const int maxn=1e5+10;
int n,c,s[maxn];
bool judge(int x)
{
    int ans=1,be=1,fe=1;
    while(fe<=n)
    {
        fe++;
        if(s[fe]-s[be]>=x)
            be=fe,ans++;
    }
        return ans>=c;
}
int main()
{
    cin>>n>>c;
    for(int i=1;i<=n;i++)
        cin>>s[i];
    sort(s+1,s+1+n);
    int l=1,r=*max_element(s+1,s+1+n);
    while(r>=l)
    {
        int mid=(r-l)/2+l;
        if(judge(mid))
            l=mid+1;
        else
            r=mid-1;
    }
    cout<<l-1;
    return 0;
}

第二题:
Little Nastya has a hobby, she likes to remove some letters from word, to obtain another word. But it turns out to be pretty hard for her, because she is too young. Therefore, her brother Sergey always helps her.

Sergey gives Nastya the word t and wants to get the word p out of it. Nastya removes letters in a certain order (one after another, in this order strictly), which is specified by permutation of letters’ indices of the word t: a1… a|t|. We denote the length of word x as |x|. Note that after removing one letter, the indices of other letters don’t change. For example, if t = “nastya” and a = [4, 1, 5, 3, 2, 6] then removals make the following sequence of words “nastya” “nastya” “nastya” “nastya” “nastya” “nastya” “nastya”.

Sergey knows this permutation. His goal is to stop his sister at some point and continue removing by himself to get the word p. Since Nastya likes this activity, Sergey wants to stop her as late as possible. Your task is to determine, how many letters Nastya can remove before she will be stopped by Sergey.

It is guaranteed that the word p can be obtained by removing the letters from word t.

Input
The first and second lines of the input contain the words t and p, respectively. Words are composed of lowercase letters of the Latin alphabet (1 ≤ |p| < |t| ≤ 200 000). It is guaranteed that the word p can be obtained by removing the letters from word t.

Next line contains a permutation a1, a2, …, a|t| of letter indices that specifies the order in which Nastya removes letters of t (1 ≤ ai ≤ |t|, all ai are distinct).

Output
Print a single integer number, the maximum number of letters that Nastya can remove.

Examples
Input

ababcba
abb
5 3 4 1 7 6 2
Output
3
Input
bbbabb
bb
1 6 3 4 2 5
Output
4
第二次训练赛总结(二分)_第1张图片
**总结:**对于这种二分题二分法部分差不多都是模板,但judge()部分有很大区别,因为疫情期间没怎么写代码,对于字符数组cin输入都忘了,还有streln计算字符数组长度都忘了。而且也没想到在定义一个数组ju[]记录s1数组中的删除数,导致我这一题没写出来。这题思路就是通过二分枚举满足的删除数,然后通过二分找到最大的删除数。
代码:

#include
#include
#include
using namespace std;
const int maxn=2e5+10;
char s1[maxn],s2[maxn];
int num[maxn],ju[maxn],le1,le2;
bool judge(int x){
    memset(ju,0,sizeof(ju));
    int p=1,sum=0;
for(int i=1;i<=x;i++){
    ju[num[i]]=1;
}
for(int i=1;i<=le1;i++){
    if(!ju[i]&&s1[i]==s2[p]){
        sum++;
        p++;
    }
    if(p>le2)
        break;
}
return sum>=le2;
}
int main()
{
    cin>>s1+1;//这样让字符数组从1开始输入,注意下面的strlen里面也要这样写。
    cin>>s2+1;
    le1=strlen(s1+1);//这里不需要减一,你从1开始输入,那么strlen也是从1开始计算!
    le2=strlen(s2+1);
    for(int i=1;i<=le1;i++)
        cin>>num[i];
    int l=1,r=le1;
    while(r>=l){
            int mid=(r-l)/2+l;
        if(judge(mid))
        l=mid+1;
    else
        r=mid-1;
    }
    cout<<l-1;
    return 0;

}
//strlen测试!!!
//#include
//#include
//using namespace std;
//int main()
//{
//    char s[100];
//    cin>>s+1;//这样的方法输入只能是字符数组!
//    for(int i=1;i<=3;i++)
//        cout<
//    cout<
//    return 0;
//测试结果说明字符数组你从那开始输入,那么streln就从那开始计算长度。
//并且只有字符数组才可以用cin直接输入。
//}

第四题:D - Snowball
Today’s morning was exceptionally snowy. Meshanya decided to go outside and noticed a huge snowball rolling down the mountain! Luckily, there are two stones on that mountain.

Initially, snowball is at height h and it has weight w. Each second the following sequence of events happens: snowball’s weights increases by i, where i — is the current height of snowball, then snowball hits the stone (if it’s present at the current height), then snowball moves one meter down. If the snowball reaches height zero, it stops.

There are exactly two stones on the mountain. First stone has weight u1 and is located at height d1, the second one — u2 and d2 respectively. When the snowball hits either of two stones, it loses weight equal to the weight of that stone. If after this snowball has negative weight, then its weight becomes zero, but the snowball continues moving as before.

Find the weight of the snowball when it stops moving, that is, it reaches height 0.

Input
First line contains two integers w and h — initial weight and height of the snowball (0≤w≤100; 1≤h≤100).

Second line contains two integers u1 and d1 — weight and height of the first stone (0≤u1≤100; 1≤d1≤h).

Third line contains two integers u2 and d2 — weight and heigth of the second stone (0≤u2≤100; 1≤d2≤h; d1≠d2). Notice that stones always have different heights.

Output
Output a single integer — final weight of the snowball after it reaches height 0.

Examples
Input

4 3
1 1
1 2
Output
8
Input
4 3
9 2
0 1
Output
1
Note
In the first example, initially a snowball of weight 4 is located at a height of 3, there are two stones of weight 1, at a height of 1 and 2, respectively. The following events occur sequentially:

The weight of the snowball increases by 3 (current height), becomes equal to 7.
The snowball moves one meter down, the current height becomes equal to 2.
The weight of the snowball increases by 2 (current height), becomes equal to 9.
The snowball hits the stone, its weight decreases by 1 (the weight of the stone), becomes equal to 8.
The snowball moves one meter down, the current height becomes equal to 1.
The weight of the snowball increases by 1 (current height), becomes equal to 9.
The snowball hits the stone, its weight decreases by 1 (the weight of the stone), becomes equal to 8.
The snowball moves one meter down, the current height becomes equal to 0.
Thus, at the end the weight of the snowball is equal to 8.
**思考:**这可以说是本次最简单的题了,但却是在我写出来的题中最浪费我时间的题(虽然我就写出来了两道emm但都是因为这道题),首先是我太急了,看这题简单就直接写,在没申请题的情况下WA了两三次(以后不能那么急了),还有这题中有个边界我没考虑,就是起点也可能有石头。导致我一直没写出来,后面的题都没心情写了,直接给我写崩溃了。以后一定要充分考虑条件。
模拟雪球下落过程。
代码:

#include
using namespace std;
const int maxn=100+10;
int hh[maxn];
int main()
{
    int w,h;
    cin>>w>>h;
    int w1,h1,w2,h2;
    cin>>w1>>h1>>w2>>h2;
    hh[h1]=w1;
    hh[h2]=w2;
    int s=w;
    for(int i=h;i>0;i--)
    {
        s+=i;
        s=((s-hh[i])>0)?(s-hh[i]):0;
    }
    cout<<s;
    return 0;
}

第五题:E - Squares and Segments

第二次训练赛总结(二分)_第2张图片
**思考:**当时这题感觉之前写过类似的,然后当时没写出来,感觉自己现在也不一定写出来,然后看了这题一我却考虑错方向了,考虑复杂了。
应该这样考虑:
第二次训练赛总结(二分)_第3张图片
然而我的考虑的确实这样。我晕死了。

第二次训练赛总结(二分)_第4张图片
以后应该充分考虑,当考虑复杂的时候再考虑能不能有简单的思路。
如果是图一的思路的话,那就先定义两边x、y都记为1,输入n当x*y>=n的时候跳出循环,循环里面则是,x>y时y++,否则x++。最后输出x、y的和就行了。

#include
using namespace std;
int main()
{
int n;
cin>>n;
int x=1,y=1;
while(x*y<n){
    if(x>y)
        y++;
    else x++;
}
cout<<x+y;
return 0;
}

**第六题:F - Postcard **

第二次训练赛总结(二分)_第5张图片
**思考:**在我下面做的时候我死活ac不了,难受死了。最后发现*前面的一个数可以重复无数次,而我当时没审清题,认为只能重复一次,就一直死在 test18。应该充分审清题之后再写代码,好好看题目的举例。这题就分类讨论就行了,首先是记录数字如的字母的个数,记录k。当k大于字母数的时候,如果雪花数为零就是Impossible,否则就将第一个雪花直线的字母输出k-字母数遍,当k小于字母数的时候,如果雪花数和?数小于字母数减去k就Impossible,否则就将字母数减去k个雪花或?见面的字母不输出,当k等于字母数的时候,就输出所有字母就行了。
代码:

#include
#include
using namespace std;
char s[210];
int k;
int main()
{
    cin>>s+1;
    int n=strlen(s+1);
    cin>>k;
    int n1=0,n2=0;
    for(int i=1;i<=n;i++){
        if(s[i]=='*')
            n1++;
        else if(s[i]=='?')
            n2++;
    }
    if(k>n-n1-n2){
        if(n1==0)
            cout<<"Impossible";
        else{
                int to=k-(n-n1-n2);
            for(int i=1;i<=n;i++){
                if(s[i]>='a'&&s[i]<='z')
                    cout<<s[i];
                else if(s[i]=='*'&&s[i-1]>='a'&&s[i-1]<='z'&&to>0){
                    while(to--)
                        cout<<s[i-1];
                }
            }
        }
    }
    else if(k<n-n1-n2){
        if(n-n1-n2-k>n1+n2)
            cout<<"Impossible";
        else{
            int to=n-n1-n2-k;
            for(int i=1;i<=n;i++){
                if(s[i]>='a'&&s[i]<='z'&&(s[i+1]=='*'||s[i+1]=='?')&&to>0){
                    to--;
                    continue;
                }
                else if(s[i]>='a'&&s[i]<='z')
                    cout<<s[i];

            }
        }
    }
    else{
        for(int i=1;i<=n;i++)
        if(s[i]>='a'&&s[i]<='z')
            cout<<s[i];
    }
    return 0;
}

你可能感兴趣的:(第二次训练赛总结(二分))