P1457 城堡 The Castle

P1457 城堡 The Castle

题目描述

我们憨厚的USACO主人公农夫约翰(Farmer John)以无法想象的运气,在他生日那天收到了一份特别的礼物:一张“幸运爱尔兰”(一种彩票)。结果这张彩票让他获得了这次比赛唯一的奖品——坐落于爱尔兰郊外的一座梦幻般的城堡!

喜欢吹嘘的农夫约翰立刻回到有着吹嘘传统的威斯康辛老家开始吹嘘了, 农夫约翰想要告诉他的奶牛们关于他城堡的一切。他需要做一些吹嘘前的准备工作:比如说知道城堡有多少个房间,每个房间有多大。另外,农夫约翰想要把一面单独的墙(指两个单位间的墙)拆掉以形成一个更大的房间。 你的工作就是帮农夫约翰做以上的准备,算出房间数与房间的大小。

城堡的平面图被划分成M*N(1 <=M,N<=50)个正方形的单位,一个这样的单位可以有0到4面墙环绕。城堡周围一定有外墙环绕以遮风挡雨。(就是说平面图的四周一定是墙。)

请仔细研究下面这个有注解的城堡平面图:

友情提示,这个城堡的平面图是7×4个单位的。一个“房间”的是平面图中一个由“#”、“-”、“|”围成的格子(就是图里面的那一个个的格子)。比如说这个样例就有5个房间。(大小分别为9、7、3、1、8个单位(排名不分先后))

移去箭头所指的那面墙,可以使2个房间合为一个新房间,且比移去其他墙所形成的房间都大。(原文为:Removing the wall marked by the arrow merges a pair of rooms to make the largest possible room that can be made by removing a single wall. )

城堡保证至少有2个房间,而且一定有一面墙可以被移走。

输入输出格式

输入格式:

第一行有两个整数:M和N 城堡的平面图用一个由数字组成的矩阵表示,一个数字表示一个单位,矩阵有N行M列。输入与样例的图一致。

每一个单位的数字告诉我们这个单位的东西南北是否有墙存在。每个数字是由以下四个整数的某个或某几个或一个都没有加起来的。

1: 在西面有墙

2: 在北面有墙

4: 在东面有墙

8: 在南面有墙

城堡内部的墙会被规定两次。比如说(1,1)南面的墙,亦会被标记为(2,1)北面的墙。

输出格式:

输出包含如下4行:

第 1 行: 城堡的房间数目。

第 2 行: 最大的房间的大小

第 3 行: 移除一面墙能得到的最大的房间的大小

第 4 行: 移除哪面墙可以得到面积最大的新房间。

选择最佳的墙来推倒。有多解时选最靠西的,仍然有多解时选最靠南的。同一格子北边的墙比东边的墙更优先。

用该墙的南邻单位的北墙或西邻单位的东墙来表示这面墙,方法是输出邻近单位的行数、列数和墙的方位("N"(北)或者"E"(东))。

输入输出样例

输入样例#1:

7 4
11 6 11 6 3 10 6
7 9 6 13 5 15 5
1 10 12 7 13 7 5
13 11 10 8 10 12 13

输出样例#1:

5
9
16
4 1 E

说明

USACO 2.1

翻译来自NOCOW

这个题不难 不知道大家对处理墙有没有好方法

我在这里介绍一个

题目说墙的号码是 1 2 4 8

这四个数显然都是2的n次幂

这里有一个性质 就是 1 2 4 8四个数可以组成1-15之内的任意一个数

且每个数只有一种组成方式

15就是1+2+4+8

14就是2+4+8

13就是1+4+8

12就是4+8

。。。。。

所以 每一个数字 代表了唯一的一种情况

我们就可以 判断了

输出墙  按照如下顺序遍历 只找北墙和东墙

#include <cstdio>
#include <cctype>
#include <cstring>
#include <algorithm>

const int MAXN=600;
const int MAXM=4000;

int n,m,id,ans,mx;

int f[MAXN][MAXN],sum[MAXM],d[MAXM][4],belong[MAXM];

bool vis[MAXN][MAXN];

int x[4]={0,1,0,-1};
int y[4]={1,0,-1,0};

struct node {
	int to;
	int next;
};

inline void read(int&x) {
	register char c=getchar();
	for(x=0;!isdigit(c);c=getchar());
	for(;isdigit(c);x=x*10+c-48,c=getchar());
}

inline int max(int a,int b) {return a<b?b:a;}

inline void cal(int now,int p) {
	if(p>=8) d[now][1]=1,p-=8;else d[now][1]=0;
	if(p>=4) d[now][0]=1,p-=4;else d[now][0]=0;
	if(p>=2) d[now][3]=1,p-=2;else d[now][3]=0;
	if(p>=1) d[now][2]=1,p-=1;else d[now][2]=0;
}

void DFS(int the_x,int the_y) {
	int now=(the_x-1)*m+the_y;
	cal(now,f[the_x][the_y]);
	vis[the_x][the_y]=true;
	belong[now]=id;
	++sum[id];
	mx=max(sum[id],mx);
	for(int i=0;i<4;++i) {
		int next_x=the_x+x[i];
		int next_y=the_y+y[i];
		if(next_x<1||next_y<1||next_x>n||next_y>m) continue;
		if(vis[next_x][next_y]||d[now][i]) continue;
		DFS(next_x,next_y);
	}
}

int hh() {
	read(m);read(n);
	for(int i=1;i<=n;++i)
	  for(int j=1;j<=m;++j)
	    read(f[i][j]);
	for(int i=1;i<=n;++i)
	  for(int j=1;j<=m;++j)
	  	if(!vis[i][j]) ++id,DFS(i,j);
	printf("%d\n%d\n",id,mx);
	ans=-1;char p;
	int b_x,b_y;
	for(int j=1;j<=m;++j)
	 for(int i=n;i>=1;--i)  {
	 	if(d[(i-1)*m+j][3]&&i!=1) {
			if(belong[(i-1)*m+j]!=belong[(i-2)*m+j])
			  if(sum[belong[(i-1)*m+j]]+sum[belong[(i-2)*m+j]]>ans)
			    b_x=i,b_y=j,ans=sum[belong[(i-1)*m+j]]+sum[belong[(i-2)*m+j]],p=‘N‘;
		}
	 	if(d[(i-1)*m+j][0]&&j!=m) {
	  		if(belong[(i-1)*m+j]!=belong[(i-1)*m+j+1])
	  		  if(sum[belong[(i-1)*m+j]]+sum[belong[(i-1)*m+j+1]]>ans)
	  		    b_x=i,b_y=j,ans=sum[belong[(i-1)*m+j]]+sum[belong[(i-1)*m+j+1]],p=‘E‘;
		}
	  }
	printf("%d\n%d %d %c\n",ans,b_x,b_y,p);
	return 0;
} 

int sb=hh();
int main(int argc,char**argv){;}

  

时间: 2024-12-25 18:20:24

P1457 城堡 The Castle的相关文章

洛谷P1457 城堡 The Castle

P1457 城堡 The Castle 137通过 279提交 题目提供者该用户不存在 标签USACO 难度提高+/省选- 提交  讨论  题解 最新讨论 暂时没有讨论 题目描述 我们憨厚的USACO主人公农夫约翰(Farmer John)以无法想象的运气,在他生日那天收到了一份特别的礼物:一张“幸运爱尔兰”(一种彩票).结果这张彩票让他获得了这次比赛唯一的奖品——坐落于爱尔兰郊外的一座梦幻般的城堡! 喜欢吹嘘的农夫约翰立刻回到有着吹嘘传统的威斯康辛老家开始吹嘘了, 农夫约翰想要告诉他的奶牛们关

洛谷—— P1457 城堡 The Castle

https://www.luogu.org/problem/show?pid=1457 题目描述 我们憨厚的USACO主人公农夫约翰(Farmer John)以无法想象的运气,在他生日那天收到了一份特别的礼物:一张“幸运爱尔兰”(一种彩票).结果这张彩票让他获得了这次比赛唯一的奖品——坐落于爱尔兰郊外的一座梦幻般的城堡! 喜欢吹嘘的农夫约翰立刻回到有着吹嘘传统的威斯康辛老家开始吹嘘了, 农夫约翰想要告诉他的奶牛们关于他城堡的一切.他需要做一些吹嘘前的准备工作:比如说知道城堡有多少个房间,每个房间

BZOJ3399: [Usaco2009 Mar]Sand Castle城堡

3399: [Usaco2009 Mar]Sand Castle城堡 Time Limit: 3 Sec  Memory Limit: 128 MBSubmit: 22  Solved: 17[Submit][Status] Description 约翰用沙子建了一座城堡.正如所有城堡的城墙,这城墙也有许多枪眼,两个相邻枪眼中间那部分叫作“城齿”.    城墙上一共有N(1≤N≤25000)个城齿,每一个都有一个高度Mi.(1≤尬≤100000).现在约翰想把城齿的高度调成某种顺序下的Bi,B2

3399: [Usaco2009 Mar]Sand Castle城堡

3399: [Usaco2009 Mar]Sand Castle城堡 Time Limit: 3 Sec  Memory Limit: 128 MBSubmit: 37  Solved: 32[Submit][Status][Discuss] Description 约翰用沙子建了一座城堡.正如所有城堡的城墙,这城墙也有许多枪眼,两个相邻枪眼中间那部分叫作“城齿”.    城墙上一共有N(1≤N≤25000)个城齿,每一个都有一个高度Mi.(1≤尬≤100000).现在约翰想把城齿的高度调成某种

[BZOJ3399] [Usaco2009 Mar]Sand Castle城堡(排序)

3399: [Usaco2009 Mar]Sand Castle城堡 Time Limit: 3 Sec  Memory Limit: 128 MBSubmit: 79  Solved: 66[Submit][Status][Discuss] Description 约翰用沙子建了一座城堡.正如所有城堡的城墙,这城墙也有许多枪眼,两个相邻枪眼中间那部分叫作"城齿".    城墙上一共有N(1≤N≤25000)个城齿,每一个都有一个高度Mi.(1≤尬≤100000).现在约翰想把城齿的高

BZOJ 3399 [Usaco2009 Mar]Sand Castle城堡(贪心)

[题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=3399 [题目大意] 将一个集合调整成另一个集合中的数,把一个数+1需要消耗x,-1需要消耗y,问最小消耗. [题解] 显然两个集合排序之后一一对应调整需要消耗的才是最少的,所以排序计算答案即可. [代码] #include <cstdio> #include <algorithm> using namespace std; const int N=25010; int

[USACO2.1.1]The Castle城堡

还以为要打很长呢. 1 #include<cstdio> 2 #define N 51 3 #define repu(i,x,y) for(i=x;i<=y;i++) 4 #define max(a,b) (a>b?a:b) 5 int n,m,a[N][N],f[N][N],x=0,s[N*N]; 6 int dfs(int x,int y,int t) { 7 f[x][y]=t; int i,j,k=4,s=1; 8 if (!(a[x][y]&1) &&am

USACO 2.1 The Castle

题目大意:给你一个城堡让你求有多少房间,最大房间有多大,敲掉一堵墙后最大的房间有多大,敲掉那座墙 思路:比较恶心的bfs题,反正就是bfs使劲敲 /*{ ID:a4298442 PROB:castle LANG:C++ } */ #include<iostream> #include<cstdio> #include<fstream> #include<queue> #include<algorithm> #define pii pair<

完美攻略心得之圣魔大战3(Castle Fantisia)艾伦希亚战记(艾伦西亚战记)包含重做版(即新艾伦希亚战记)

(城堡幻想曲3,纠正大家个错误哦,不是圣魔大战3,圣魔大战是城堡幻想曲2,圣魔大战不是个系列,艾伦西亚战记==艾伦希亚战记,一个游戏日文名:タイトル キャッスルファンタジア -エレンシア戦記-リニューアル,日文攻略:艾伦西亚战记(艾伦希亚战记)日文攻略) 本文经过几天的改动,应该是完美了(8个MM都追到了,当然我不会就此结束,还会继续改动),我针对重作版和我玩的情况对文章进行补充,因为版本号不同,有些地方仅仅能參考了,我玩的是重做版汉化第二版(详细看城堡幻想曲圣魔大战3(Castle Fanti