首页 > 其他 > 详细

JOI 2019 Final 硬币收藏

时间:2019-10-26 16:19:01      阅读:75      评论:0      收藏:0      [点我收藏+]

题面

题解

在合理区域内每个点的状态初始化为-1
先把每个硬币都放入离它最近的合理区域内
后详解见下

代码

#include <cstdio>
#include <iostream>
#include <cmath>
#define ll long long
#define file(x) freopen(x".in","r",stdin);freopen(x".out","w",stdout);
using namespace std;
inline int read(){
    int x=0,f=1;char c=getchar();
    while (c>'9'||c<'0') {if (c=='-') f=-1;c=getchar();}
    while (c>='0'&&c<='9') {x=(x<<1)+(x<<3)+(c^48);c=getchar();}
    return x*f;
}
const int maxn(1e5+5);
int n;
int v[maxn][3];
ll ans;
ll a,b;
void init(){
    n=read();
    for (int i(1);i<=n;++i)
        for (int j(1);j<=2;++j)
        v[i][j]=-1;
    for (int i(1);i<=n+n;++i){
        int x=read(),y=read();
        if (x<1) ans+=1-x,x=1;
        if (x>n) ans+=x-n,x=n;
        if (y<1) ans+=1-y,y=1;
        if (y>2) ans+=y-2,y=2;
        v[x][y]+=1;
    }
}

void doit(){
    for (int i(1);i<=n;++i){
        a+=v[i][1],b+=v[i][2];//a、b分别存储第一行、第二行的当前状态下的多余的硬币数量(当其为负的时候表示缺少的)
        if (a<0&&b>0){//第一行缺少硬币,第二行来补
            int s=min(b,-a);ans+=s,b-=s,a+=s;
        }
        if (a>0&&b<0){//第二行缺少,第一行来补
            int s=min(a,-b);ans+=s,a-=s,b+=s;
        }
        if (i<n) ans+=abs(a)+abs(b);//多余的硬币(欠缺的)向右边传递
    }
    printf("%lld\n",ans);    
}

signed main(){
//  file("coin");
    init();
    doit();
    return 0;
}

JOI 2019 Final 硬币收藏

原文:https://www.cnblogs.com/cancers/p/11743295.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!