HDU 6879 - Mine Sweeper

题意

定义《扫雷》游戏的地图中每个空白格子的值为其周围八个格子内地雷的数量(即游戏内临近地雷数量的提示)

则一张地图的值\(S\)为所有空白格子的值总和

现给定\(S\),要求构造出一张长度与宽度均不超过\(25\)的地图,使其值等于\(S\)

限制

\(1\leq T\leq 1001\)

\(0\leq S\leq 1000\)

思路

这题过的人数应该是最多的,所以肯定是存在比我的想法更优更方便的解的

但是题解写的不是很清楚,所以还是写下了这篇博客(画图好累……)

发现\(T_{max}=|S|\),范围内每个值肯定都会问一遍,考虑预处理所有方案(在线输出好像也没有问题的样子)

首先发现,如果一个地雷周围没有其他地雷,也没有障碍物(表示它不在图的边界上)

那么这个地雷对于答案的贡献就是\(8\)

考虑所有地雷都互不相邻的情况(一个地雷周围一圈不存在其他地雷)

由于图最大尺寸为\(25\times 25\)

地雷分布情况为\((2,2),(2,4),\dots,(2,24),(4,2),(4,4),\dots,(24,24)\)

这样总共能放置\(12\times 12=144\)个对答案贡献为\(8\)的地雷

由于\(144\times 8>1000\),这样的分布绰绰有余

所以得到一个结论:只要\(S\)为\(8\)的倍数,那么它一定有解


首先考虑\(S\lt 8\)的所有情况

当\(S=0\)时,直接输出一个\(1\times 1\)的空图即可

当\(S=1\)时

当\(S=2\)时

当\(S=3\)时

当\(S=4\)时

当\(S=5\)时

当\(S=6\)时

当\(S=7\)时


既然已经能够确定一个数的倍数一定有解了,那我们可以尝试找找看能否依托\(8\)来找出其他情况

也就是把\(S\geq 8\)的所有情况看成以下的形式之一表示

\[\left \{
\begin{aligned}
8&k\\
8&k+1\\
8&k+2\\
8&k+3\\
8&k+4\\
8&k+5\\
8&k+6\\
8&k+7\\
\end{aligned}
\right \}
,\ k\in \Z
\]

对于\(S=8k+1\)的情况:

在\((1,1)\)的位置多放置一个地雷,可以使得原本位于\((2,2)\)的地雷对答案的贡献由\(8\)变成\(9\),且不影响其他地雷的贡献

对于\(S=8k+2\)的情况:

在\((1,1)\)与\((1,2)\)的位置多放置两个地雷,可以使得原本位于\((2,2)\)的地雷对答案的贡献由\(8\)变成\(10\),且不影响其他地雷的贡献

对于\(S=8k+3\)的情况:

在\((1,2)\)的位置多放置一个地雷,可以使得原本位于\((2,2)\)的地雷对答案的贡献由\(8\)变成\(11\),且不影响其他地雷的贡献

对于\(S=8k+4\)的情况:

在\((1,2)\)与\((2,1)\)的位置多放置两个地雷,可以使得原本位于\((2,2)\)的地雷对答案的贡献由\(8\)变成\(12\),且不影响其他地雷的贡献

对于\(S=8k+5\)的情况:

仅先看放置贡献为\(8\)的地雷,假设最后一个放置的地雷位于第\(i\)行

为了不影响它对答案的贡献,那么第\(i+1\)行不能放东西

由上面\(S=5\)的情况可得,我们可以将其上下倒置放在第\(i+2\)行,从而防止其对其他地雷贡献造成影响

(边界限制可行性证明在下面)

对于\(S=8k+6\)的情况:

参考\(S=6\),同样的,为了不产生冲突,只能放置在第\(i+2\)行

对于\(S=8k+7\)的情况:

由于\(S=7\)的情况里地雷需要占两行

所以要将\(S=7\)的情况倒置放在\(S=8k\)的第\(i+2\)行与第\(i+3\)行

(边界限制可行性证明在下面)


直接证明\(S=8k+7\)时需要用到\(i+3\)行的可行性情况吧

由于\(S\)最大为\(1000\),如果全部使用贡献为\(8\)的地雷方案填充地图,最多只需要\(125\)个地雷

每行最多能放置\(12\)个这种方案的地雷,那么最多只需要用到第\(11\)行过

对于原图,由于地雷在行之间也需要空一行,故\(i\)的最大值为\(22\)

\(22+3=25\),恰好满足题目要求,故方案可行


综上,本题所有\(S\)情况均有解,预处理后直接输出即可

注意,\(S=8k\)的情况最后也需要输出\(i+1\)行(最后一行空着,以保证有空格子让地雷做出贡献,即让最后一行的地雷非边界)

示例

如果没大看懂上面的例子,这里放几张截图领会一下大致意思即可















代码

(0ms~31ms/1000ms)

#include<bits/stdc++.h>
using namespace std; int mp[1010][28][28];
int maxCol[1010]; void init()
{
for(int i=8;i<=1000;i++)
{
int les=i/8,j,k;
for(j=2;j<=24;j+=2)
{
for(k=2;k<=24;k+=2)
{
mp[i][j][k]=1;
if(--les==0)
break;
}
if(les==0)
break;
}
switch(i%8)
{
case 0:
maxCol[i]=j+1;
break;
case 1:
mp[i][1][1]=1;
maxCol[i]=j+1;
break;
case 2:
mp[i][1][1]=mp[i][1][2]=1;
maxCol[i]=j+1;
break;
case 3:
mp[i][1][2]=1;
maxCol[i]=j+1;
break;
case 4:
mp[i][1][2]=mp[i][2][1]=1;
maxCol[i]=j+1;
break;
case 5:
mp[i][j+2][2]=1;
maxCol[i]=j+2;
break;
case 6:
mp[i][j+2][1]=mp[i][j+2][2]=1;
maxCol[i]=j+2;
break;
case 7:
mp[i][j+3][1]=mp[i][j+3][2]=mp[i][j+2][1]=1;
maxCol[i]=j+3;
break;
}
}
} int main()
{
init();
int T,S;
scanf("%d",&T);
while(T--)
{
scanf("%d",&S);
if(S>=8)
{
printf("%d 25\n",maxCol[S]);
for(int i=1;i<=maxCol[S];i++)
{
for(int j=1;j<=25;j++)
{
if(mp[S][i][j])
putchar('X');
else
putchar('.');
}
putchar('\n');
}
}
else if(S==0)
{
puts("1 1");
puts(".");
}
else if(S==1)
{
puts("1 2");
puts("X.");
}
else if(S==2)
{
puts("1 3");
puts("X.X");
}
else if(S==3)
{
puts("2 2");
puts("X.");
puts("..");
}
else if(S==4)
{
puts("2 2");
puts("X.");
puts("X.");
}
else if(S==5)
{
puts("2 3");
puts(".X.");
puts("...");
}
else if(S==6)
{
puts("2 3");
puts("XX.");
puts("...");
}
else if(S==7)
{
puts("3 3");
puts("XX.");
puts("X..");
puts("...");
}
}
return 0;
}

2020杭电多校 10C / HDU 6879 - Mine Sweeper (构造)的更多相关文章

  1. 2020杭电多校 C / HDU 6879 - Mine Sweeper

    题意: t组输入,每组输入一个s 你需要输出一个r行c列的阵列,这个阵列中'X'代表炸弹,'.'表示没有炸弹 对于'.'这些位置都会有一个数值,这个值取决于这个位置附近8个位置,这8个位置一共有几个炸 ...

  2. 【2020杭电多校】Distinct Sub-palindromes 找规律

    题目链接:Distinct Sub-palindromes 题意: 给你一个长度n,你需要找出来一些串,这些串由A...Z和a...z构成.我们设长度为n的所有串中所包含回文子串最少的数量为ans.问 ...

  3. 【2020杭电多校】 Lead of Wisdom、The Oculus

    题目链接:Lead of Wisdom 题意:有n个物品,这些物品有k种类型.每种物品有对应的类型ti,其他值ai,bi,ci,di 你可以选择一些物品,但是这些物品要保证它们任意两者之间类型不能相同 ...

  4. 【2020杭电多校】Total Eclipse 并查集+思维

    题目链接:Total Eclipse 题意: t组输入,给你一个由n个点,m条边构成的图,每一个点的权值是ai.你每一次可以选择一批联通的点,然后让他们的权值都减去1.问最后把所有点的权值都变成0需要 ...

  5. 可持久化线段树的学习(区间第k大和查询历史版本的数据)(杭电多校赛第二场1011)

    以前我们学习了线段树可以知道,线段树的每一个节点都储存的是一段区间,所以线段树可以做简单的区间查询,更改等简单的操作. 而后面再做有些题目,就可能会碰到一种回退的操作.这里的回退是指回到未做各种操作之 ...

  6. 2018 Multi-University Training Contest 1 杭电多校第一场

    抱着可能杭电的多校1比牛客的多校1更恐怖的想法 看到三道签到题 幸福的都快哭出来了好吗 1001  Maximum Multiple(hdoj 6298) 链接:http://acm.hdu.edu. ...

  7. HDU 4941 Magical Forest(map映射+二分查找)杭电多校训练赛第七场1007

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4941 解题报告:给你一个n*m的矩阵,矩阵的一些方格中有水果,每个水果有一个能量值,现在有三种操作,第 ...

  8. HDU 4902 Nice boat 2014杭电多校训练赛第四场F题(线段树区间更新)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4902 解题报告:输入一个序列,然后有q次操作,操作有两种,第一种是把区间 (l,r) 变成x,第二种是 ...

  9. HDU 5821 Ball (贪心排序) -2016杭电多校联合第8场

    题目:传送门. 题意:T组数据,每组给定一个n一个m,在给定两个长度为n的数组a和b,再给定m次操作,每次给定l和r,每次可以把[l,r]的数进行任意调换位置,问能否在转换后使得a数组变成b数组. 题 ...

随机推荐

  1. 【JavaWeb】Filter 过滤器

    Filter 过滤器 简介 Filter 过滤器是 JavaWeb 三大组件之一 Filter 过滤器是 JavaEE 的规范,也就是接口 Filter 过滤器的作用是 拦截请求,过滤响应 拦截请求的 ...

  2. 【C++】《Effective C++》第六章

    第六章 继承与面向对象设计 条款32:确定你的public继承塑模出is-a关系 public隐含的寓意:每个派生类对象同时也是一个基类对象,反之不成立.只不过基类比派生类表现出更一般化的概念,派生类 ...

  3. jenkins 构建历史 显示版本号

    0   jenkins 安装此插件: 此插件名为 " groovy postbuild " 1  效果图: 2   安装插件: 系统管理 --> 插件管理 --> 可选 ...

  4. MySQL where 条件字句查询

    where 条件字句 搜索条件可由一个或多个逻辑表达式组成 , 结果一般为布尔值 逻辑运算符 运算符 语法 描述 and && a and b a && b 逻辑与 两 ...

  5. mysql的逻辑备份和恢复

    备份指定的数据库或此数据库中的某些表 mysqldump [options] db_name [tables] >backup.sql 备份指定的一个或多个数据库 mysqldump --dat ...

  6. ctfhub技能树—彩蛋

    彩蛋题建议大家首先自己动手去找一找 做 好 准 备 后 再 看 下 文 !           1.首页 使用域名查询工具查询子域名 2.公众号 此题关注ctfhub公众号即可拿到,不过多赘述. 3. ...

  7. 创建并使用https证书

    目录 前言 产生证书 测试https服务器 用tls加密tcp连接 总结 前言 https要比http更安全些,因此可以配置Nginx服务器使用证书,客户端就会去第三方平台校验证书. 但是我们自己的服 ...

  8. poj 1038 Bugs Integrated, Inc. 题解

    提供一种代码难度比较简单的做法(可能) 状态表示: 设置状态$ f[i][j] $,表示第 \(i\) 行状态为 \(j\) 的最大放置数,因为这是个阴间题,因为题目内存设置很小,所以要用滚动数组,存 ...

  9. Scrapy——將爬取圖片下載到本地

    1. Spider程序: 1 import scrapy, json 2 from UnsplashImageSpider.items import ImageItem 3 4 class Unspl ...

  10. 如何实现new,call,apply,bind的底层原理。

    new做了什么? new是用来实例化对象的,当new了一个对象后 1.创建一个新对象 2.将构造函数的作用域赋值给新对象(this指向新对象) 3.执行构造函数里面的代码(为这个新对象添加属性) 4. ...