Problem solving report of the first training competition

Posted by freakus_maximus on Thu, 20 Jan 2022 00:00:11 +0100

I made 4 questions in the training competition, supplemented 4 questions after the competition, and finally used word to complete the problem-solving report, which showed 9 questions

Number of supplementary questions: 8 / 10

Harvest feeling: this training competition is a summary of our lessons since the winter vacation. I feel that my learning is not solid at all. The knowledge of prefix and difference is very simple, but when I meet specific problems, it makes me very difficult. My foundation is not solid. I always care about the amount of questions. The questions I make are not classified and summarized, and the questions I can't do are not reflected and summarized, I think a lot, but it's very hard to take action. I still need to brush more questions. If only I could have a problem brushing website with basic algorithms, I still need to continue my efforts. I hope I won't be swept out by acm. I'm very happy and humble to study in this big family jpg.

I will study the algorithm with my senior students. I hope I can calm down and analyze some very long problems, study hard, and can't be half hearted.

Through this training competition, I strengthened my understanding of some basic algorithms such as prefix, difference and binary algorithm, and realized the gap between myself and others. In the next training, I will continue to listen and learn algorithm knowledge.

A: Lucky numbers https://vjudge.csgrandeur.cn/problem/51Nod-2091

Idea: violent cycle: divide the number in each interval by 10 after taking the remainder of 10, until 7 of the number in the interval outputs the number, and stop the cycle.

Investigation content: circulation

#include<bits/stdc++.h>
using namespace std;
int main()
{
int l,r;
scanf("%d%d",&l,&r);
int flag=0;
for(int i=l;i<=r;i++)
{
   int x=i;
   while(x!=0)
   {
    if(x%10==7)
    {
    printf("%d\n",i);
    flag=1;
    break;
}
x=x/10;
   }
}
if(flag==0)
{
printf("None\n");
}
return 0;
}

B: Binary search (5)

https://vjudge.csgrandeur.cn/problem/%E8%AE%A1%E8%92%9C%E5%AE%A2-T1555

Dichotomous template question

#include<bits/stdc++.h>
using namespace std;
int a[1000000];
int main()
{
int n,m;
scanf("%d%d",&n,&m);//Why comment??
for(int i=0;i<n;i++)
scanf("%d",&a[i]);
sort(a,a+n);
while(m--)
{
int x;
scanf("%d",&x);
if(x<a[0])
{
printf("-1\n");
continue;
    }
    if(x>=a[n-1])
    {
     printf("%d\n",a[n-1]);
     continue;
}
int l=0,r=n-1;
while(l<r)
{
int mid=(r+l+1)/2;
if(a[mid]<=x)
{
l=mid;
    }
else
r=mid-1;
 }
 cout<<a[l]<<endl;
}
return 0;
}

C (supplementary): Hai Balai stack

https://vjudge.csgrandeur.cn/problem/SPOJ-HAYBALE

Investigation contents: difference, prefix and

Idea: add a bale of hay directly to the input interval through the difference, and then find the prefix sum of the difference score array and sort it. Because n is an odd number, just take the median directly.

Reflection: I'm afraid to see such a long English question and give up directly. It's too long. I'm flustered and hope to get rid of this problem.

#include<cstdio>
#include<algorithm>
using namespace std;
const int N=1000005;
int w[N],a[N];
int main()
{
    int n,k,x,y;
scanf("%d%d",&n,&k);
while(k--)
{
scanf("%d%d",&x,&y);
w[x]++;
w[y+1]--;
}
for(int i=1;i<=n;++i)
a[i]=a[i-1]+w[i];
sort(a+1,a+n+1);
printf("%d",a[n/2+1]);
return 0;
}

D: Maximum subarray

https://vjudge.csgrandeur.cn/problem/%E8%AE%A1%E8%92%9C%E5%AE%A2-21

Investigation content: double pointer, less data, violence is OK.

Idea: violence, define a pointer j to move down, add each value to the comparison of the previous value, and replace it if it is greater than. The maximum value is output until all numbers are traversed.

#include<bits/stdc++.h>
using namespace std;
int a[1010];
int main()
{
int n;
scanf("%d",&n);
int sum1=0,sum=0;
for(int i=0;i<n;i++)
{
scanf("%d",&a[i]);
}
sum=a[0];
for(int i=0;i<n;i++)
{
sum1=0;
for(int j=i;j<n;j++)
{
sum1+=a[j];
if(sum1>sum)
sum=sum1;
    }
}
printf("%d\n",sum);
return 0;
}

E: Laser bomb

https://vjudge.csgrandeur.cn/problem/%E8%AE%A1%E8%92%9C%E5%AE%A2-T2431

Investigation content: prefix and of two-dimensional array

Idea: define a two-dimensional array A. for the input x,y, compare it with r each time to determine the boundary of the square, two-dimensional prefix and operation. Enumerate the coordinates (i,j) in the lower right corner of the square with side length R, find the sum of all values in the square, and then update the answer.

#include<bits/stdc++.h>
using namespace std;
const int N=5010;
int a[N][N];
int main()
{
int N,R;
scanf("%d%d",&N,&R);
int n=R,m=R;
while(N--)
{
int x,y,v;
scanf("%d%d%d",&x,&y,&v);
x++,y++;
n=max(n,x);
m=max(m,y);
a[x][y]+=v;
}
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
a[i][j]+=a[i-1][j]+a[i][j-1]-a[i-1][j-1];
}
}
int sum=0;
for(int i=R;i<=n;i++)
{
for(int j=R;j<=m;j++)
{
sum=max(sum,a[i][j]-a[i-R][j]-a[i][j-R]+a[i-R][j-R]);
}
}
printf("%d\n",sum);
return 0;
}

F (supplementary): Hate "A"

https://vjudge.csgrandeur.cn/problem/CodeForces-1146B

Idea: from the Internet, traverse the str string and divide it into two strings. One is the string suf without a and the other is the pre with string. Judge whether the total length is equal to the length of the original string while adding it. Until the end of the cycle, if there is no result, output ": (".

#include<bits/stdc++.h>
using namespace std;
int main(){
string str,pre,suf;
cin >> str;
for(auto c : str){
pre += c;
if(c != 'a') suf += c;
if(pre.size() + suf.size() == str.size() && pre + suf == str){
cout << pre << endl;
return 0;
}
} 
cout << ":(" << endl;
return 0;
}

I (supplementary): very male and female

https://vjudge.csgrandeur.cn/problem/%E8%AE%A1%E8%92%9C%E5%AE%A2-T1853

Inspection contents: prefix and, double pointer.

Idea: define girls as - 1 and boys as 1. Define array S as the prefix sum of per array. As long as the prefix sum of two positions is found to be equal, they are equal continuous subsequences between men and women. We record each prefix and the position of the first occurrence. The next occurrence minus the position of the first occurrence is the length.

#include <iostream>
using namespace std;
const int N=1e5+10;
int per[N],s[N];
int main(){
    int n,i,j,max=0;
    cin>>n;
    for(i=1;i<=n;i++){
        scanf("%d",&per[i]);
        if(per[i]==0) per[i]=-1;
        s[i]=s[i-1]+per[i];
    }
    for(i=1;i<=n;i++){
        for(j=0;j<i;j++){
            if(s[i]==s[j]){
                if(i-j>max)
                    max=i-j;
                break;
            }
        }
    }
    cout<<max;
    return 0;
}

H (make-up): road laying

https://vjudge.csgrandeur.cn/problem/%E8%AE%A1%E8%92%9C%E5%AE%A2-T2050

Content: greedy algorithm

Idea: traverse the road array: if the previous block is smaller than the latter, the counter adds its difference, because in this way, the depth of the first pit is set to - 0. When a pit is deeper than the previous pit, the number of additional operations required relative to the number of stored operations is its difference

#include<iostream>
#include<cstdio>
using namespace std;
int n,ans=0,l=0;
int main()
{
    scanf("%d",&n);
    for(int a=1;a<=n;a++)
    {
        int p;
        scanf("%d",&p);//Current depth
        if(p>l)//If the current depth is greater than the previous depth
        {
            ans=ans+p-l;//Total steps plus current depth minus previous depth
        }
        l=p;//Depth of the previous section;
    }
    printf("%d\n",ans);
}