2019_8_6 模拟赛

111 篇文章 0 订阅
76 篇文章 0 订阅

前言

我太菜了,虽然现在感觉过水,但是比赛时是全脸懵逼,但是思路真的太水了


T1 蛋糕切割(过水)


T2 膜拜神牛(过水)


T3 矩形统计

题目

有一张边长为 N N N的方格纸(有若干破损),问这张纸能够裁出多少矩形。


分析

类比于POJ 2559,可以把某一行的某一个方格向上延伸,这样形成一个柱形图,其实在其基础上修改就行了,要用到单调栈,详见代码


代码

#include <cstdio>
#define rr register
using namespace std;
int n,abo[1011],w[1011],rk[1011],tot; long long ans;
signed main(){
	scanf("%d",&n);
	for (rr int i=1;i<=n;++i)
	for (rr int j=1,tot=0;j<=n+1;++j){
		rr char c;
		if (j<n+1){
		    for (c=getchar();c!=48&&c!=49;c=getchar());
		    abo[j]=(c^49)?(abo[j]+1):0;
		}
		rr int width=0;
		while (tot&&abo[j]<abo[rk[tot]]){
			ans+=1ll*(width+1)*w[tot]*abo[rk[tot]];//w[tot]表示目前将删去的柱形宽度,width表示已删去的柱形宽度,那么当前求的是可以选择已删去的柱形和未删去柱形最靠右的位置都没有算过,从这些位置开始向左延伸w[tot]宽,可以选择最多abo[rk[tot]]的高度
			width+=w[tot],--tot;
		}
		rk[++tot]=j,w[tot]=width+1;
	}
	return !printf("%lld",ans);
}

T4 逃亡路径(过水)


T5 矩形反色

题目

wyc有一个无限大的方格图,由无限个1*1的格子构成,每个格子有黑白两色。初始所有格子都是白色。
现在wyc会进行n次操作,每次把一个矩形区域反色(即黑变白,白变黑),求n次操作后得出的图形的周长(即边界长)。
边界的定义:定义一条长度为1的线段在边界上,当且仅当这条线段两侧的格子颜色不同。


分析

通过dalao的打表找规律可以发现,某条边可行当且仅当该边被覆盖了奇数次,所以说可以行和列分别处理,对于同行或同列离散得到相邻端点所组成的边被覆盖次数,用差分实现


代码

#include <cstdio>
#include <cctype>
#include <algorithm>
#define rr register
using namespace std;
const int N=100101;
struct rec{int row,l,r;}a[N],b[N];
int c[N],rk[N],sum[N],n,ans;
inline signed iut(){
	rr int ans=0; rr char c=getchar();
	while (!isdigit(c)) c=getchar();
	while (isdigit(c)) ans=(ans<<3)+(ans<<1)+(c^48),c=getchar();
	return ans;
}
bool cmp(rec x,rec y){return x.row<y.row;}
inline void rc(rec *a){
	for (rr int L=0,R=L;L<n;L=R+1,R=L){
		while (a[R].row==a[R+1].row) ++R;
		rr int tot=0;
		for (rr int i=L;i<=R;++i) c[tot]=a[i].l,c[++tot]=a[i].r,++tot;
		sort(c,c+tot); tot=unique(c,c+tot)-c;
		for (rr int i=0;i<tot;++i) rk[c[i]]=i,sum[i]=0;
		for (rr int i=L;i<=R;++i) ++sum[rk[a[i].l]],--sum[rk[a[i].r]];
		for (rr int i=0;i<tot-1;++i) sum[i+1]+=sum[i];
		for (rr int i=0;i<tot-1;++i) ans+=(sum[i]&1)?(c[i+1]-c[i]):0;
	}
}
signed main(){
	n=iut()<<1;
	for (rr int i=0;i<n;i+=2){
		rr int x1=iut(),y1=iut(),x2=iut()+1,y2=iut()+1;
		a[i]=(rec){x1,y1,y2},a[i^1]=(rec){x2,y1,y2},
		b[i]=(rec){y1,x1,x2},b[i^1]=(rec){y2,x1,x2};
	}
	sort(a,a+n,cmp),sort(b,b+n,cmp);
	rc(a),rc(b);
	return !printf("%d",ans);
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值