AtCoder Beginner Contest 168 F . (Single Dot) 需要设定边界的染色

AtCoder Beginner Contest 168   比赛人数10873  奇了怪,比赛一开始,就看到所有题.刚打完CodeForces,体力不支

AtCoder Beginner Contest 168  F   . (Single Dot)   需要设定边界的染色

总目录详见https://blog.csdn.net/mrcrack/article/details/104454762

在线测评地址https://atcoder.jp/contests/abc168/tasks/abc168_f

思路,该题,难在边界的设定,具体,可结合代码与图进行研究。

样例构图如下

样例1

Input:
5 6
1 2 0
0 1 1
0 2 2
-3 4 -1
-2 6 3
1 0 1
0 1 2
2 0 2
-1 -4 5
3 -2 4
1 2 4
Output:
13

 边界设置说明如下:

如上图所示,cow向左,不能越过(-3,4,-1);cow向右,不能越过(-2,6,3)

因int k[][2]={{-1,0},{1,0},{0,-1},{0,1}};//L(0),R(1),U(2),D(3)
border[x][y][移动方向]==1表示此时到达了边界
cow向左,不能越过(-3,4,-1);数据设置如下,具体可见代码
border[(-1)][(-3)][0]=1  表示(-1,-3)是左边界,不能向左移动
border[(-1)][(-2)][0]=1
border[(-1)][(-1)][0]=1
border[(-1)][(0)][0]=1
border[(-1)][(1)][0]=1
border[(-1)][(2)][0]=1
border[(-1)][(3)][0]=1

border[(-2)][(-3)][1]=1
border[(-2)][(-2)][1]=1
border[(-2)][(-1)][1]=1
border[(-2)][(0)][1]=1
border[(-2)][(1)][1]=1
border[(-2)][(2)][1]=1
border[(-2)][(3)][1]=1

cow向右,不能越过(-2,6,3).数据设置如下,具体可见代码
border[(2)][(-2)][1]=1  表示(2,-2)是右边界,不能向右移动
border[(2)][(-1)][1]=1
border[(2)][(0)][1]=1
border[(2)][(1)][1]=1
border[(2)][(2)][1]=1
border[(2)][(3)][1]=1
border[(2)][(4)][1]=1
border[(2)][(5)][1]=1

border[(3)][(-2)][0]=1
border[(3)][(-1)][0]=1
border[(3)][(0)][0]=1
border[(3)][(1)][0]=1
border[(3)][(2)][0]=1
border[(3)][(3)][0]=1
border[(3)][(4)][0]=1
border[(3)][(5)][0]=1

 如上图所示,cow向上,不能越过(-1,-4,5);cow向下,不能越过(3,-2,4)

因int k[][2]={{-1,0},{1,0},{0,-1},{0,1}};//L(0),R(1),U(2),D(3)
border[x][y][移动方向]==1表示此时到达了边界
cow向上,不能越过(-1,-4,5);数据设置如下,具体可见代码
border[(-4)][(-1)][2]=1  表示(-4,-1)是上边界,不能向上移动
border[(-3)][(-1)][2]=1
border[(-2)][(-1)][2]=1
border[(-1)][(-1)][2]=1
border[(0)][(-1)][2]=1
border[(1)][(-1)][2]=1
border[(2)][(-1)][2]=1
border[(3)][(-1)][2]=1
border[(4)][(-1)][2]=1

border[(-4)][(-2)][3]=1
border[(-3)][(-2)][3]=1
border[(-2)][(-2)][3]=1
border[(-1)][(-2)][3]=1
border[(0)][(-2)][3]=1
border[(1)][(-2)][3]=1
border[(2)][(-2)][3]=1
border[(3)][(-2)][3]=1
border[(4)][(-2)][3]=1

cow向下,不能越过(3,-2,4).数据设置如下,具体可见代码
border[(-2)][(3)][2]=1
border[(-1)][(3)][2]=1
border[(0)][(3)][2]=1
border[(1)][(3)][2]=1
border[(2)][(3)][2]=1
border[(3)][(3)][2]=1

border[(-2)][(2)][3]=1  表示(-2,2)是下边界,不能向下移动
border[(-1)][(2)][3]=1
border[(0)][(2)][3]=1
border[(1)][(2)][3]=1
border[(2)][(2)][3]=1
border[(3)][(2)][3]=1

样例2

Input:
6 1
-3 -1 -2
-3 -1 1
-2 -1 2
1 4 -2
1 4 -1
1 4 1
3 1 4
Output:
INF

AC代码如下

#include <cstdio>
#include <algorithm>
#define LL long long
#define INF 2000000000
#define maxn 1010
using namespace std;
int n,m;
int k[][2]={{-1,0},{1,0},{0,-1},{0,1}};//L,R,U,D
int border[maxn][maxn][4];//边界
int vis[maxn][maxn],qx[maxn*maxn],qy[maxn*maxn];
LL ans;
struct node{
	int a,b,c;
}f[maxn],g[maxn];
int X[maxn],Y[maxn],XN,YN;//值到脚标,离散化
int findX(int v){
	return lower_bound(X,X+XN,v)-X;//功能:查找非递减序列[first,last) 内第一个大于或等于某个元素的位置。
}
int findY(int v){
	return lower_bound(Y,Y+YN,v)-Y;
}
void bfs(int xx,int yy){
	int i,h,t,nx,ny,x,y;
	h=t=0;
	qx[t]=xx,qy[t]=yy,t++,vis[xx][yy]=1;
	while(h<t){
		x=qx[h],y=qy[h],h++;
		ans+=(LL)(X[x+1]-X[x])*(Y[y+1]-Y[y]);//根据此句编写The point (0,0) does not lie on any of the given segments.
		for(i=0;i<4;i++){//四个方向
			if(border[x][y][i])continue;
			nx=x+k[i][0],ny=y+k[i][1];
			if(nx==0||nx==XN-1||ny==0||ny==YN-1){//到达-INF,INF表示无线延伸
				ans=-1;
				return;
			}
			if(vis[nx][ny])continue;//该点已经访问过
			vis[nx][ny]=1,qx[t]=nx,qy[t]=ny,t++;
		}
	}
}
void init(){
	int i,x,y,r,j;
	scanf("%d%d",&n,&m);
	for(i=0;i<n;i++)scanf("%d%d%d",&f[i].a,&f[i].b,&f[i].c),X[XN++]=f[i].c;
	X[XN++]=-INF,X[XN++]=INF;//设定值的范围
	sort(X,X+XN);//自小到大排序
	XN=unique(X,X+XN)-X;//去重
	for(i=0;i<m;i++)scanf("%d%d%d",&g[i].a,&g[i].b,&g[i].c),Y[YN++]=g[i].a;
	Y[YN++]=-INF,Y[YN++]=INF;
	sort(Y,Y+YN);//自小到大排序
	YN=unique(Y,Y+YN)-Y;
	for(i=0;i<n;i++){
		x=findX(f[i].c);
		r=findY(f[i].b);
		if(Y[r]!=f[i].b)r--;//找不到的情况,需要--
		for(j=findY(f[i].a);j<r;j++)
			border[x-1][j][1]=border[x][j][0]=1;//边界设定:1表示,向右不能到达;0表示,向左不能到达
	}
	for(i=0;i<m;i++){
		y=findY(g[i].a);
		r=findX(g[i].c);
		if(X[r]!=g[i].c)r--;
		for(j=findX(g[i].b);j<r;j++)
			border[j][y-1][3]=border[j][y][2]=1;//边界设定:3表示,向下不能到达;2表示,向上不能到达
	}
}
int main(){
	init();
	bfs(findX(0)-1,findY(0)-1);//根据此句编写The point (0,0) does not lie on any of the given segments.
	if(ans==-1)printf("INF\n");
	else printf("%lld\n",ans);
	return 0;
}

此题成文,耗时3天。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值