Solution to a problem [JOI 2019 Final] coin collection

Face questions

Resolve

First, the title can be interpreted as some point into a box, each grid can only put a.

Then obviously you can put this point to the nearest box of the grid,

(This time the grid can put a lot more)

Then in the boxRun aboutmobile.

So let's consider only one line,

At this coin can only move left and right.

Thus an array can start \ (f [i] \) recording the grid This has several coins.

But the difference is that the initial value of the tub \ (- 1 \) .

That put a coin in the value of the grid is \ (0 \) .

Then from \ (1 \) to the \ (n-\) traversal,

If \ (f [i] <0 \) that it needs to move over the right side of the coin,

And \ (f [i]> 0 \) will be described herein that the coin to go to the right.

Then \ (F [I +. 1] + = F [I] \) , it represents the next to spread the demand,

And \ (ANS = F + [I] \) , because \ (f [i] \) coin movement of a grid.

(The above paragraph is preferably read which together Reevaluation)

Then there are two lines, then it is just one more move up and down,

Since the vertical movement is not worse than the right and left movable.

So consider can move up and down, and then transferred on the line.

code:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <set>
#include <algorithm>
#define int long long
#define pii pair<int,int>
#define fi first
#define sc second
#define fre(x) freopen(x".in","r",stdin),freopen(x".out","w",stdout)
using namespace std;

inline int read(){
    int sum=0,f=1;char ch=getchar();
    while(ch>'9'||ch<'0'){if(ch=='-')f=-1;ch=getchar();}
    while(ch>='0'&&ch<='9'){sum=sum*10+ch-'0';ch=getchar();}
    return f*sum;
}

const int N=1000005;
struct node{int x,y;}a[N];
int n,tot,ans;
int f[N][3];

signed main(){
    n=read();
    for(int i=1;i<=(n<<1);i++) a[i].x=read(),a[i].y=read();
    for(int i=1;i<=n;i++) f[i][1]=f[i][2]=-1;
    for(int i=1;i<=(n<<1);i++){
        int xx=max((int)1,min(a[i].x,n)),yy=max((int)1,min(a[i].y,(int)2));
        ans+=abs(xx-a[i].x)+abs(yy-a[i].y);
        f[xx][yy]++;
    }
    for(int i=1;i<=n;i++){
        if(f[i][1]>0&&f[i][2]<0){
            int ret=min(abs(f[i][1]),abs(f[i][2]));
            f[i][1]-=ret;f[i][2]+=ret;
            ans+=ret;
        }
        else if(f[i][1]<0&&f[i][2]>0){
            int ret=min(abs(f[i][1]),abs(f[i][2]));
            f[i][2]-=ret;f[i][1]+=ret;
            ans+=ret;
        }
        ans+=abs(f[i][1]+f[i][2]);
        f[i+1][1]+=f[i][1];f[i+1][2]+=f[i][2];
    }
    printf("%lld\n",ans);
    return 0;
}

Guess you like

Origin www.cnblogs.com/zsq259/p/11743722.html