题目传送门

思路

肯定食用dfs啦。。。

但关键是两条船接触了怎么判断呢??

上图:

可以发现一下规律

当两条船接触时,必有一条直线连续穿过两条船

当一条船不与另一条船接触时,没有一条直线连续穿过两条船

所以只需要在每一次碰见一条船的一部分(一条船内每个点都要拓展一遍)时,将其沿右上、左下分别拓展一遍,边拓展边用sum前缀和check一遍就好啦。。。。

核心代码:

//码风很丑,勿喷
int k=1;
while(a[i+k][j+k]==1) k++;//找到最左下的一个点(即连线段的另一个端点)
--k;//别忘了再加回来
int hh=sum[i+k][j+k]-sum[i-1][j]-sum[i][j-1]+sum[i-1][j-1];//前缀和
++k;
if(hh<k*k){//前缀和必须是k*k(一个正方形)
puts("Bad placement.");
return 0;//强制结束
}//沿右上
k=1;//清零
while(a[i+k][j-k]==1) ++k;//找到最左下的一个点(即连线段的另一个端点)
--k;
hh=sum[i+k][j]-sum[i-1][j]-sum[i+k][j-k-1]+sum[i-1][j-k-1];//前缀和
++k;//别忘了再加回来
if(hh<k*k){//前缀和必须是k*k(一个正方形)
puts("Bad placement.");
return 0;//强制结束
}//沿左下

如果没有接触的话,可以直接dfs啦。。。代码简洁:

void dfs(int x,int y){
if(vis[x][y]==1) return ;//如果已经拓展过直接退出
vis[x][y]=1;//标记
if(a[x][y+1]==1) dfs(x,y+1);//向四个方向拓展,标记为此船
if(a[x-1][y]==1) dfs(x-1,y);
if(a[x+1][y]==1) dfs(x+1,y);
if(a[x][y-1]==1) dfs(x,y-1);
}

所有代码:(非常“简洁”。。。)

#include<bits/stdc++.h>
using namespace std;
inline int read(){
int ret=0,f=1;char ch=getchar();
while (ch<'0'||ch>'9') {if (ch=='-') f=-f;ch=getchar();}
while (ch>='0'&&ch<='9') ret=ret*10+ch-'0',ch=getchar();
return ret*f;
}//丑陋的读优
void write(int x){
if(x<0){
putchar('-');
write(-x);
return ;
}
if(x<10) putchar(x+'0');
else{
write(x/10);
putchar(x%10+'0');
}
}//丑陋的输优
int n,m,a[1010][1010],sum[1010][1010];
int vis[1010][1010],ans;
void dfs(int x,int y){
if(vis[x][y]==1) return ;
vis[x][y]=1;
if(a[x][y+1]==1) dfs(x,y+1);
if(a[x-1][y]==1) dfs(x-1,y);
if(a[x+1][y]==1) dfs(x+1,y);
if(a[x][y-1]==1) dfs(x,y-1);
}//丑陋的dfs
int main(){
n=read();m=read();
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
char ch;cin>>ch;
if(ch=='#') a[i][j]=1;
}
}//读入
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
sum[i][j]=sum[i-1][j]+sum[i][j-1]-sum[i-1][j-1]+a[i][j];
}
}//前缀和
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
if(a[i][j]==1){
int k=1;
while(a[i+k][j+k]==1) k++;
--k;
int hh=sum[i+k][j+k]-sum[i-1][j]-sum[i][j-1]+sum[i-1][j-1];
++k;
if(hh<k*k){
puts("Bad placement.");
return 0;
}
k=1;
while(a[i+k][j-k]==1) ++k;
--k;
hh=sum[i+k][j]-sum[i-1][j]-sum[i+k][j-k-1]+sum[i-1][j-k-1];
++k;
if(hh<k*k){
puts("Bad placement.");
return 0;
}
}//不想再提了。。。判断船只是否接触
}
}
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
if(a[i][j]==1&&vis[i][j]==0){
++ans;
dfs(i,j);
}//dfs统计答案
}
}
cout<<"There are ";
write(ans);
cout<<" ships.";putchar('\n');//输出
return 0;//结束。。。。
}
/*************************
用时: 102ms / 内存: 5152KB
代码:1.63KB C++
By yuzhengxi
**************************/

洛谷P1331 海战 题解的更多相关文章

  1. 洛谷P1331海战

    题目描述 在峰会期间,武装部队得处于高度戒备.警察将监视每一条大街,军队将保卫建筑物,领空将布满了F-2003飞机.此外,巡洋船只和舰队将被派去保护海岸线. 不幸的是因为种种原因,国防海军部仅有很少的 ...

  2. 洛谷——P1331 海战

    P1331 海战 题目描述 在峰会期间,武装部队得处于高度戒备.警察将监视每一条大街,军队将保卫建筑物,领空将布满了F-2003飞机.此外,巡洋船只和舰队将被派去保护海岸线.不幸的是因为种种原因,国防 ...

  3. 洛谷 P1331 海战

    传送门 题解:由于船是方形的,所以比较简单.但是考试的时候跪了,orz.忘了考虑类似一圈井号中间有一摊水.          可以只考虑这个点上方和左边点的情况,这样分为四种情况.一种是左边是一滩水, ...

  4. 洛谷P1331 海战

    海战 题目链接 这还是一道联通块的题,只是需要判断是否存在以下四种情况: o. .o oo oo oo oo o. .o 如果存在就是Bad placement. 要注意标记以下,不然会出现多次输出B ...

  5. 洛谷NOIp热身赛题解

    洛谷NOIp热身赛题解 A 最大差值 简单树状数组,维护区间和.区间平方和,方差按照给的公式算就行了 #include<bits/stdc++.h> #define il inline # ...

  6. 洛谷P2827 蚯蚓 题解

    洛谷P2827 蚯蚓 题解 题目描述 本题中,我们将用符号 ⌊c⌋ 表示对 c 向下取整. 蛐蛐国最近蚯蚓成灾了!隔壁跳蚤国的跳蚤也拿蚯蚓们没办法,蛐蛐国王只好去请神刀手来帮他们消灭蚯蚓. 蛐蛐国里现 ...

  7. 洛谷P1816 忠诚 题解

    洛谷P1816 忠诚 题解 题目描述 老管家是一个聪明能干的人.他为财主工作了整整10年,财主为了让自已账目更加清楚.要求管家每天记k次账,由于管家聪明能干,因而管家总是让财主十分满意.但是由于一些人 ...

  8. [POI 2008&洛谷P3467]PLA-Postering 题解(单调栈)

    [POI 2008&洛谷P3467]PLA-Postering Description Byteburg市东边的建筑都是以旧结构形式建造的:建筑互相紧挨着,之间没有空间.它们共同形成了一条长长 ...

  9. [NOI 2020 Online] 入门组T1 文具采购(洛谷 P6188)题解

    原题传送门 题目部分:(来自于考试题面,经整理) [题目描述] 小明的班上共有 n 元班费,同学们准备使用班费集体购买 3 种物品: 1.圆规,每个 7 元. 2.笔,每支 4 元. 3.笔记本,每本 ...

随机推荐

  1. shiro权限认证与授权

    什么是shiro? Shiro是apache旗下一个开源框架,它将软件系统的安全认证相关的功能抽取出来,实现用户身份认证,权限授权.加密.会话管理等功能,组成了一个通用的安全认证框架. 为什么要用sh ...

  2. P3572 [POI2014]PTA-Little Bird

    P3572 [POI2014]PTA-Little Bird 一只鸟从1跳到n.从1开始,跳到比当前矮的不消耗体力,否则消耗一点体力,每次询问有一个步伐限制k,求每次最少耗费多少体力 很简短的题目哼. ...

  3. 动态规划:树形DP-景点中心(树的带权重心)

    话说宁波市的中小学生在镇海中学参加计算机程序设计比赛,比赛之余,他们在镇海中学的各个景点参观.镇海中学共有n个景点,每个景点均有若干学生正在参 观.这n个景点以自然数1至n编号,每两个景点的编号均不同 ...

  4. Ubuntu下快速部署安装 Nginx + PHP + MySQL 笔记

        先更新软件库 sudo apt-get update 安装 MySQL sudo apt-get install mysql-server 安装 Nginx sudo apt-get inst ...

  5. Java实现链式存储的二叉查找树(递归方法)

    二叉查找树的定义: 二叉查找树或者是一颗空树,或者是一颗具有以下特性的非空二叉树: 1. 若左子树非空,则左子树上所有节点关键字值均小于根节点的关键字: 2. 若右子树非空,则右子树上所有节点关键字值 ...

  6. Scrapy可视化管理软件SpiderKeeper

    通常开发好的Scrapy爬虫部署到服务器上,要不使用nohup命令,要不使用scrapyd.如果使用nohup命令的话,爬虫挂掉了,你可能还不知道,你还得上服务器上查或者做额外的邮件通知操作.如果使用 ...

  7. 20155322 2016-2017-2 《Java程序设计》第7周学习总结

    20155322 2016-2017-2 <Java程序设计>第7周学习总结 教材学习内容总结 第七周学习的主要内容是课本的第十二第十三章: 第十二章主要内容: "Lambda ...

  8. # 20155209 2016-2017-2 《Java程序设计》第六周学习总结

    20155209 2016-2017-2 <Java程序设计>第六周学习总结 教材学习内容总结 java中I/O操作主要是指使用Java进行输入,输出操作. Java所有的I/O机制都是基 ...

  9. 15、BigDecimal类简介

    BigDecimal类概述 由于在运算的时候,float类型和double很容易丢失精度,在金融.银行等对数值精度要求非常高的领域里面,就不能使用float或double了,为了能精确的表示.计算浮点 ...

  10. 2018ICPC青岛赛区J题

    题目链接:http://acm.zju.edu.cn/onlinejudge/showRuns.do?contestId=1 这题真的坑,为什么要买0本书的时候,书架里面刚好有价格为0的时候输出&qu ...