Codeforces Round #662 (Div. 2) AD problem solution

Codeforces Round #662 (Div. 2) AD problem solution
//Written in the large rating value of 2184/2184, the small rating value of 1881/1881
//This game is played with the trumpet, the ranking is 78, the rating value + 219
//A handed a false conclusion for
nothing , and D wrote two wrong subscripts for two variables... //People can never avoid making low-level mistakes and can only avoid them as much as possible...

Contest link: https://codeforces.com/contest/1393 Question
A
Time to pass: 5 minutes (1 time penalty)
Simple conclusion

I won’t explain it in detail. My way of thinking is to start with n being an odd number.
It is easy to get that when n is odd, the case of n+2 requires one more operation than the case of n.
In the case of n+1, the number of constructions cannot exceed the case of n+2.
From this, n=1 corresponds to answer 1, n=2,3 corresponds to answer 2, n=4,5 corresponds to answer 3...

#include<bits/stdc++.h>
#define ll long long
#define IOS ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
using namespace std;

int32_t main()
{
    
    
    IOS;
    int t;
    cin>>t;
    while(t--)
    {
    
    
        ll n;
        cin>>n;
        cout<<(n+2)/2<<endl;
    }
}

Question B
Time to pass: 13 minutes
implementation, model conversion

First of all, don’t understand the meaning of the question wrong (for example, I read it wrong at the beginning). The
question means that we use n sticks of various lengths at the beginning. After q times, we increase or decrease a certain length of sticks. Can these wooden sticks be used to construct a rectangle and a square after this increase or decrease operation? You only need to use these wooden sticks to form the perimeter of the rectangle and square, and only one stick can be placed on each side.

So let's summarize the characteristics of square and rectangle: a
square needs 4 wooden sticks of equal length, and a
rectangle needs 2 pairs of wooden sticks of equal length.

Four square sticks of equal length can actually be regarded as two pairs of wooden sticks of equal length. In fact, the number of pairs of wooden sticks of equal length required to construct a rectangle and a square is 4 , but at the same time We also need to meet a condition, that is, we have more than 4 sticks of the same length.

Therefore, we need to maintain the number of pairs of wooden sticks of equal length and the number of lengths with more than 4 sticks in the process of increasing and decreasing. These two values ​​are sufficient.

The length ranges from 1 to 1e5. First, perform a bucket sorting and use the num[x] array to record the number of sticks of length x. In the initial state, calculate the logarithm cas2 of wooden sticks of equal length, num[x]>=4 The number of x cas4.
Then change the value of num array and cas2, cas4 according to the increase and decrease operation:
+x operation: In
this case, the number of sticks of length x is increased. If num[x]=3, increase num[x] Change to 4, cas4 + 1
If num[x] is an odd number, it can be increased to form a pair of equal length sticks. In the case of cas2 + 1
-x operation: In
this case, the length x is The number of bars is reduced. If num[x]=4, num[x] becomes 3 after the reduction. In the case of cas4, -1
If num[x] is an even number, the reduction will form a pair of equal lengths. In the case of cas2, -1
can construct a square + rectangle, cas4 is not 0, and cas2>=4

#include<bits/stdc++.h>
#define ll long long
#define IOS ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
using namespace std;
const ll maxn=1e5+7;

ll num[maxn];

int32_t main()
{
    
    
    IOS;
    int n;
    cin>>n;
    for(ll i=0;i<n;i++)
    {
    
    
        ll x;
        cin>>x;
        num[x]++;
    }
    ll cas2=0,cas4=0;
    for(ll i=1;i<=100000;i++)
    {
    
    
        cas2+=num[i]/2;
        if(num[i]>3) cas4++;
    }
    ll q;
    cin>>q;
    while(q--)
    {
    
    
        char c;
        ll x;
        cin>>c>>x;
        if(c=='-')
        {
    
    
            if(num[x]==4) cas4--;
            if(num[x]%2==0) cas2--;
            num[x]--;
        }
        else
        {
    
    
            if(num[x]==3) cas4++;
            if(num[x]%2) cas2++;
            num[x]++;
        }
        if(cas4&&cas2>3) cout<<"YES"<<endl;
        else cout<<"NO"<<endl;
    }
}

Question C
: Time to pass: 10min
greedy, structure, conclusion

Given you n numbers, now you need to arrange these numbers in a certain order so that the smallest value of the spacing between numbers with equal values ​​is the largest.

Although the phrase "minimum maximum" is a classic dichotomous feature at first sight... but in fact, this question directly greets the conclusion O(n).

Take this set of data as an example:
14
1 1 1 2 2 2 3 3 3 4 4 6 7 8

We first find out the maximum number of occurrences of these numbers through bucket sorting, and record it as Max. In this example, Max=3.
The numbers with 3 occurrences are 1, 2, and 3 respectively.

Regardless of other numbers, we use sequential spaced placement: 1, 2, 3...1,2,3...1,2,3
This construction method makes the distance between numbers with equal values ​​as large as possible. The distance value is Max-1=2.

Notice the empty area indicated by the ellipsis "..." in the above structure. This empty area is used to place the remaining numbers. Note that the number of empty areas is Max-1, and the number of occurrences of other remaining numbers will not be equal to Max at most, that is, it can only be the same as the number of empty areas at most, equal to Max-1, for example, for the number 4 It has appeared twice, and we continue to place an average of 4 in these empty areas.

The final answer is Max-1 plus the smallest number of digits placed in each empty area. Therefore, we have to make the smallest number of digits in these empty areas as large as possible, so we use the average The way it is placed.

After placing 4, the effect is 1, 2, 3, 4...1,2,3,4...1,2,3. The final effect is 1,2,3, 4,6,8 1,2,3, 4,7, 1,2,3.

Record the number of digits whose number of occurrences is equal to Max as cas, then the number of numbers other than these digits is equal to n-Max × \times× cas, the number of empty areas is Max-1.
Without considering the empty area, the distance between the numbers with the same value is Max-1. After the empty area is added, the answer will increase by the value (n-Max× \times× cas)/(Max-1).
The final answer is Max-1+(n-Max× \times×cas)/(Max-1)。

#include<bits/stdc++.h>
#define ll long long
#define IOS ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
using namespace std;
const ll maxn=1e5+7;
int32_t main()
{
    
    
    IOS;
    int t;
    cin>>t;
    while(t--)
    {
    
    
        ll n;
        cin>>n;
        vector<ll>num(n+1,0);
        ll Max=0;
        for(ll i=0;i<n;i++)
        {
    
    
            ll x;
            cin>>x;
            num[x]++;
            Max=max(Max,num[x]);
        }
        ll cas=0;
        for(ll i=1;i<=n;i++)
            if(num[i]==Max) cas++;
        cas+=(n-Max*cas)/(Max-1);
        cout<<cas-1<<endl;
    }
}


Question D
: Time to pass: 44min (two rounds of time penalty, great discomfort for nothing)
dp

First of all, brute force search is bound to time out, so you can calculate the complexity yourself.

My way of thinking is this:
For each position, we record that there are at most several adjacent positions with the same color as the current one, and at most several adjacent positions with the same color as the current downward. The smaller of these two values ​​is the maximum distance that our current position can simultaneously expand outward in the vertical direction.

We use field_d[i][j] (the calculation method of this data does not need to be said) to record the maximum distance that the position (i, j) extends in the vertical direction at the same time, and then calculate the left and direction through this data The maximum distance that the right can extend.

Field_l[i][j] Recording position (i, j) in the left direction can be extended at most the distance
transfer equation is field_l[i][j]=min(field_l[i][j-1]+1,field_d [i][j]).
The reason is that if you want to extend to the left, the extension distance of the current position in the vertical direction cannot be less than the extension distance +1 of the adjacent position on the left in the numerical direction. (This conclusion can be obtained by observing the figure required to be constructed)

field_r[i][j] The maximum distance that the recording position (i, j) can extend in the right direction. The
calculation method is the same as above

Take the smallest of the left and right extension distances, that is, the maximum extension distance from the current position, which can be added to the answer.

#include<bits/stdc++.h>
#define ll long long
#define IOS ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
using namespace std;
const ll maxn=2e3+7;

int field_u[maxn][maxn];//field_u[i][j]记录(i,j)位置向上最多有几个相邻位置和(i,j)颜色相同
int field_d[maxn][maxn];//field_u[i][j]记录(i,j)位置向下最多有几个相邻位置和(i,j)颜色相同
//最后field_d[i][j]记录的是(i,j)在竖直方向上最多可以同时延伸多少个位置,颜色都是与(i,j)相同
int field_l[maxn][maxn];
int field_r[maxn][maxn];

string s[maxn];

int32_t main()
{
    
    
    IOS;
    int n,m;
    cin>>n>>m;
    ll ans=n*m;//每个格子不向外延伸,自身构成一种答案
    for(ll i=0;i<n;i++) cin>>s[i];
    for(ll j=0;j<m;j++)//计算每个位置,在向上和向下两个方向最多可以延伸多少距离
    {
    
    
        for(ll i=1;i<n;i++)
            if(s[i][j]==s[i-1][j]) field_u[i][j]=field_u[i-1][j]+1;
        for(ll i=n-2;i>=0;i--)
            if(s[i][j]==s[i+1][j]) field_d[i][j]=field_d[i+1][j]+1;
    }
    for(ll i=0;i<n;i++)//根据上面的两个数组取最小值,为竖直方向上能同时延伸
        for(ll j=0;j<m;j++)
            field_d[i][j]=min(field_u[i][j],field_d[i][j]);
    for(ll i=0;i<n;i++)//根据竖直方向上能同时延伸的距离值,分别计算向左和向右延伸的最大距离
    {
    
    
        for(ll j=1;j<m;j++)
            if(s[i][j]==s[i][j-1]) field_l[i][j]=min(field_l[i][j-1]+1,field_d[i][j]);
        for(ll j=m-2;j>=0;j--)
            if(s[i][j]==s[i][j+1]) field_r[i][j]=min(field_r[i][j+1]+1,field_d[i][j]);
    }
    for(ll i=0;i<n;i++)
        for(ll j=0;j<m;j++)
        ans+=min(field_l[i][j],field_r[i][j]);
    cout<<ans<<endl;
}


Guess you like

Origin blog.csdn.net/StandNotAlone/article/details/107873256