• JOI 2019 Final 硬币收藏


    题面

    题解

    在合理区域内每个点的状态初始化为-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
    ",ans);    
    }
    
    signed main(){
    //	file("coin");
    	init();
    	doit();
    	return 0;
    }
    
    
  • 相关阅读:
    [Notes] 如何使用abode audition录歌
    [Tips] matlab save load
    [Tips] matlab csv格式文件读写
    [Tips] 随机数 随机序列 随机排列生成
    [Tips] csv 读写
    [record] 初入android
    HTML中表格table边框border(1px还嫌粗)的解决方案:
    CSS颜色代码大全
    ie9下面的console的bug
    js 性能优化 篇一
  • 原文地址:https://www.cnblogs.com/cancers/p/11743295.html
Copyright © 2020-2023  润新知