Solution to the problem of Luogu: P1209 [[USACO1.3] Barn Repair]

Keywords: C++

Original question portal: https://www.luogu.org/problemnew/show/P1209

First of all, this is a greedy problem.  
Let's first analyze its greedy strategy.  
For example:
4 50 18  
3
4
6
8
14
15
16
17
21
25
26
27
30
31
40
41
42
43  
The difference between them is:
1 2 2 6 1 1 1 4 4 1 1 3 1 9 1 1 1  
Since we want to minimize the length of the board, we need to vacate the first m-1 largest area, add up other areas, and then add a m (for example, the difference between 3 and 8 is 8-3 = 5, while the actual length of the board is 8-3 + 1 = 6, each board has one more, so m more boards will be added).  
Code 1 (50 point code):

#include <bits/stdc++.h>
using namespace std;
struct node
{
    int cow,div;
    /*
    cow Number of the cowshed occupied by the cow,
    div For the difference between this point and the previous point,
    _For this is a WA code,
    */
}_[201];
int m,s,c;
bool cmp(node c,node d)
{
    return c.div>d.div;
}
int main()
{
    int ans=0;
    scanf("%d%d%d",&m,&s,&c);
    scanf("%d",&_[1].cow);_[1].div=0;
    for (int i=2;i<=c;i++)
    {
        scanf("%d",&_[i].cow);
        _[i].div=_[i].cow-_[i-1].cow;
    }
    sort(_+1,_+c+1,cmp);
    for (int i=m;i<=c;i++) ans+=_[i].div;
    ans+=m;
    printf("%d\n",ans);
    return 0;
}

This is a 50 point code. Obviously, the problem is that the input number must be an ascending sequence. So, add abs and sort, and the code is:
Code 2 (80 point code):

#include <bits/stdc++.h>
using namespace std;
struct node
{
    int cow,div;
    /*
    cow Number of the cowshed occupied by the cow,
    div For the difference between this point and the previous point,
    _For this is a WA code.
    */
}_[201];
int m,s,c;
bool cmp1(node c,node d)
{
    return c.cow<d.cow;
}
bool cmp2(node c,node d)
{
    return c.div>d.div;
}
int main()
{
    int ans=0;
    scanf("%d%d%d",&m,&s,&c);
    scanf("%d",&_[1].cow);
    for (int i=2;i<=c;i++)
        scanf("%d",&_[i].cow);
    sort(_+1,_+c+1,cmp1);
    for (int i=2;i<=c;i++) _[i].div=abs(_[i].cow-_[i-1].cow);
    sort(_+1,_+c+1,cmp2);
    for (int i=m;i<=c;i++) ans+=_[i].div;
    ans+=m;
    printf("%d\n",ans);
    return 0;
}

This code is easy to think of as an AC code, but it's not. For example, test point 6 shows that M is larger than c. Then it must not be covered with m boards. At this time, we just need to place a board with a length of 1 at each point, or the total length of the board is the number of cattle. So the code is as follows:
Code 3 (100 point code):

//This problem is solved by Muyang®Provide. Muyang, konjaku.
#include <bits/stdc++.h>
using namespace std;
struct node
{
    int cow,div,_this,_last;
    /*
    cow Number of the cowshed occupied by the cow,
    div For the difference between this point and the previous point,
    _this Is the point, and "last" is the previous point.
    */
}_[201];
int m,s,c;
bool cmp1(node c,node d)
{
    return c.cow<d.cow;
}
bool cmp2(node c,node d)
{
    return c.div>d.div;
}
int main()
{
    int ans=0;
    scanf("%d%d%d",&m,&s,&c);
    if (m>=c) {printf("%d\n",c);return 0;}
    scanf("%d",&_[1].cow);_[1]._last=0;_[1]._this=1;
    for (int i=2;i<=c;i++)
        scanf("%d",&_[i].cow);
    sort(_+1,_+c+1,cmp1);
    for (int i=2;i<=c;i++) _[i].div=abs(_[i].cow-_[i-1].cow),_[i]._this=i,_[i]._last=i-1;
    sort(_+1,_+c+1,cmp2);
    for (int i=m;i<=c;i++) ans+=_[i].div;
    ans+=m;
    printf("%d\n",ans);
    return 0;
}

Posted by nadz on Thu, 05 Dec 2019 12:26:50 -0800