• 积木「CSP-S全国排位赛第一场」


    题意

    搜狗截图20191102120007.png


    思路

    首先有一点是肯定的,掉落的形状会像一个三角形一样。(因为总体的排列像砖墙一样,所以掉落范围只能缩小不能扩大)

    于是我们可以维护初始的所有区间,然后在向上转移的过程中合并区间、统计答案。

    代码

    #include <bits/stdc++.h>
    
    using namespace std;
    
    namespace StandardIO {
    
    	template<typename T>inline void read (T &x) {
    		x=0;T f=1;char c=getchar();
    		for (; c<'0'||c>'9'; c=getchar()) if (c=='-') f=-1;
    		for (; c>='0'&&c<='9'; c=getchar()) x=x*10+c-'0';
    		x*=f;
    	}
    
    	template<typename T>inline void write (T x) {
    		if (x<0) putchar('-'),x*=-1;
    		if (x>=10) write(x/10);
    		putchar(x%10+'0');
    	}
    
    }
    
    using namespace StandardIO;
    
    namespace Project {
    	#define int long long
    
    	const int N=300300;
    	
    	int n,ans;
    	pair<int,int> p[N];
    	int tot;
    	struct node {
    		int x,l,r;
    		node () {}
    		node (int _x,int _l,int _r) : x(_x),l(_l),r(_r) {}
    	} line[N];
    	
    	inline bool cmp (const pair<int,int> x,const pair<int,int> y) {
    		return x.first<y.first;
    	}
    	inline bool cmp2 (const node x,const node y) {
    		return (x.l!=y.l)?(x.l<y.l):(x.r<y.r);
    	}
    	inline void merge () {
    		int cnt=1;
    		sort(line+1,line+tot+1,cmp2);
    		for (register int i=2; i<=tot; ++i) {
    			if (line[i].l<=line[cnt].r+1) line[cnt].r=max(line[cnt].r,line[i].r);
    			else line[++cnt]=line[i];
    		}
    		tot=cnt;
    	}
    	inline void update () {
    		int cnt=0;
    		for (register int i=1; i<=tot; ++i) {
    			++line[i].l,--line[i].r;
    			if (line[i].l<=line[i].r) line[++cnt]=line[i];
    		}
    		tot=cnt;
    	}
    	
    	inline void MAIN () {
    		read(n);
    		for (register int i=1; i<=n; ++i) 
    			read(p[i].first),read(p[i].second);
    		sort(p+1,p+n+1,cmp);
    		int cur=1,top=0;
    		while (1) {
    			if (!tot) {
    				if (cur>n) break;
    				top=p[cur].first;
    			}
    			while (cur<=n&&p[cur].first==top) line[++tot]=node(p[cur].first,p[cur].second,p[cur].second+1),++cur;
    			merge();
    			for (register int i=1; i<=tot; ++i) {
    				ans+=(line[i].r-line[i].l+1)>>1;
    			}
    			update();
    			++top;
    		}
    		write(ans);
    	}
    	
    	#undef int
    }
    
    int main () {
    //	freopen(".in","r",stdin);
    //	freopen(".out","w",stdout);
    	Project::MAIN();
    }
    
    
  • 相关阅读:
    ccf 201604-3 路径解析
    ccf 201609-3 炉石传说
    ccf 201612-3 权限查询
    ccf 201709-3 JSON查询
    ccf 201703-3 Markdown
    POJ 3259 -- Wormholes
    Bellman-Ford 单源最短路径算法
    【oracle】oracle启动和关闭步骤
    【Excel】Excel根据单元格背景色求和
    【Oracle】Oracle时间日期格式
  • 原文地址:https://www.cnblogs.com/ilverene/p/11781320.html
Copyright © 2020-2023  润新知