Topic Link
\(Solution\)
First move all the pieces to the nearest target point
We set up two variables \ (ans1, ans2 \) indicates the number of pieces can be moved so far on this point, then \ (f [i] [j ] \) represents \ (i, j \) the number of pieces on , ans is the answer
If you move from left to right is positive representation
If you move from right to left is negative representation
We consider how to maintain this thing
We think of the two big cases:
- The position originally had a value
so long as we ans + (f [i] [ j] -1) to - This position would have no value
we consider three cases, we have one line, for example, the same way the rest of the line- ans1 greater than 0, then we only need to ans1--
- ans1 <0 && ans2> 0 we will ans2 -, ans + 1 represents the shift up from below (but for the first time to pay attention to a row of things, the following will speak)
- The remaining cases ans1--, represent the right to borrow from a coming.
Then will be processed after this line \ (ans1 \) and \ (ans2 \) and then we determine what ans1 and ans2 whether a positive and negative.
If you put a small absolute value that is moved to another line, plus the absolute value of the answer.
After each get that done, the answer plus \ (abs (ans1) + abs (ans) \) represents the shift to the back of these coins
\(Code\)
#include<bits/stdc++.h>
#define int long long
#define rg register
#define file(x) freopen(x".in","r",stdin);freopen(x".out","w",stdout);
using namespace std;
const int N=1e6+10;
int read(){
int x=0,f=1;char c=getchar();
while(c<'0'||c>'9') f=(c=='-')?-1:1,c=getchar();
while(c>='0'&&c<='9') x=x*10+c-48,c=getchar();
return f*x;
}
int X[N],Y[N],n,ans,flag1,flag2,ans1,ans2;
int f[N][3];
void solve(int x,int y){
int nowx=x,nowy=y;
if(x<=n&&x>=1&&y<=2&&y>=1) {f[x][y]++;return ;}
if(x>n) x=n;
if(x<1) x=1;
if(y>2) y=2;
if(y<1) y=1;
// cout<<x<<" "<<y<<endl;
f[x][y]++,ans+=abs(nowx-x)+abs(nowy-y);
}
main(){
// file("coin");
n=read();
for(int i=1;i<=2*n;i++)
X[i]=read(),Y[i]=read(),solve(X[i],Y[i]);
for(int i=1;i<=n;i++){
if(f[i][1]>1) ans1+=f[i][1]-1;
if(f[i][2]>1) ans2+=f[i][2]-1;
if(f[i][1]==0){
if(ans1>0) ans1--;
else if(ans2>0&&(ans2>1||(ans2==1&&f[i][2]))) ans2--,ans+=1;
else ans1--;
}
if(f[i][2]==0){
if(ans2>0) ans2--;
else if(ans1>0) ans1--,ans+=1;
else ans2--;
}
if(ans1<0&&ans2>0) {
if(abs(ans1)<abs(ans2))
ans2=ans2+ans1,ans+=abs(ans1),ans1=0;
else ans1=ans2+ans1,ans+=abs(ans2),ans2=0;
}
if(ans2<0&&ans1>0) {
if(abs(ans1)<abs(ans2))
ans2=ans2+ans1,ans+=abs(ans1),ans1=0;
else ans1=ans2+ans1,ans+=abs(ans2),ans2=0;
}
ans+=abs(ans1)+abs(ans2);
}
cout<<ans;
return 0;
}