2016年第31届宁波市信息学竞赛复赛试题 D 射击
题目本体
题目描述
不难发现,豆豆能从很多事情中去思考数学,于是豆豆父母决定让他去练习射击,这是项需要集中注意力的运动,相信能够让豆豆暂时脱离数学。学习射击的第一天就让豆豆产生了浓厚的兴趣,射击的靶子是大饼圆,射击枪的子弹近似圆柱,为什么要圆的不能是其他的形状呢,于是豆豆开始构思,设计了这样一个好玩的问题:N*M 的方形格子靶子,每个格子有两种状态凸或者凹(如下图浅色表示凹,深色表示凸)
现在用一个十字横截面的子弹(填充黑色部分)去射击,被射中的小格子凹变凸,凸变凹,子弹放大后的横截面如下图
这种子弹最多可以覆盖 5 个格子,如图打完后,5 个格子凹凸状态发生了变化
请问最少需要几次射击使靶子中所有小格子都呈现凹的状态。
注意:子弹中心点如果打到四个角上则只会影响 3 个格子,如下图黑色格子表示被子弹中心点正好击中左上角后覆盖的 3 个格子,如果打到除四个角的边界上,则会影响到 4 个格子,如下图右侧的 4 个黑色格子所示,这是子弹中心点打中第 3 行第 6 列时的覆盖情况。(也就是说子弹超出靶子部分不起效)
输入
第一行两个用空格隔开的数字 N 和 M(1<=N,M<=17)
接下来 N 行描述靶子中小格子的状态,‘X’表示凸,‘.’表示凹。
输出
输出所需要的最少射击次数
注意:输入数据保证有解
样例输入1
5 5
XX.XX
X.X.X
.XXX.
X.X.X
XX.XX
样例输出1
5
样例输入2
8 9
…XXXXX…
.X…X.
X…X.X…X
X…X
X.X…X.X
X…XXX…X
.X…X.
…XXXXX…
样例输出2
25
解答部分
首先,显然子弹的射击顺序不影响最终的结果;结果只受如何选择弹位和该弹位上的射击次数有关。
其次,同个弹位只有射击0次和1次两种可能。
射击两次与不射击完全相同,射击三次和射击一次完全相同,以此类推。
因此,如果我们规定了搜索的方向(比如从上到下且从左到右),那么就会有两个方向的格子(上和左)已被固定,选择好当前格子是否射击,再往后搜索的时候剩余的方向的格子(下和右)选择就会受限,这样就能进行大量的剪枝。
如果当前格子被确定为凸起,则剩余方向的格子不可同时射击或同时不射击
如果当前格子被确定为凹下,则剩余方向的格子必须同时射击或同时不射击
但这样复杂度还是不够低,还需进一步优化。
之前我们看问题的方式还是过于狭隘,只看到了其中一个点。
如果我们把一整行当成一个整体来考虑,并决定好第一行的射击方式后,我们就会发现第一行就会遗留下一个剩余状态 由 第一行的初始状态 + 第一行的射击选择 所决定。
而由于第一行的射击方式已经确定,这个第一行的剩余状态又不能100%保证达成全凹,并且从第三行开始的所有射击均无法影响第一行的剩余状态,换句话说,如果我们要让第一行的最终状态变为全凹,只能依靠对第二行进行射击选择来完成,且这种选择有且只有一种。
上一行的剩余状态为凹处,下一行同位置处必定不能射击
上一行的剩余状态为凸处,下一行同位置处必须进行射击
( 第一行的初始状态 + 第一行的射击选择 ) → 第一行的剩余状态 → 第二行的射击选择
( 第二行的初始状态 + 第二行的射击选择 + 第一行的射击选择 ) → 第二行的剩余状态 → 第三行的射击选择
( 第三行的初始状态 + 第三行的射击选择 + 第二行的射击选择 ) → 第三行的剩余状态 → 第四行的射击选择
……(以此类推)
综上所述,我们只要枚举第一行如何进行射击,为了逐行完成全凹的目标,之后每行的选择就被固定,只需逐行进行模拟,对最后一行进行判定能否完成全凹的目标,并在枚举过程中不断记录最小值即可。
模拟过程可以手动模拟,也可以用位运算来进行。
代码部分
#include<iostream>
#include<iomanip>
#include<fstream>
#include<cstdio>
#include<cstring>
#include<vector>
#include<cmath>
#include<algorithm>
using namespace std;typedef long long LL;const int MAXN=22;int Get_Effect(int,int&);int main()
{//cout<<(1<<-1)<<endl;//cout<<(59&31)<<endl;int n,m;char tmp;int mp[MAXN];memset(mp,0,sizeof(mp));cin>>n>>m;srand(10);for(int i=0; i<n; i++){for(int j=0; j<m; j++){bool rd=((rand()%2)==1);if(rd)tmp='X';else tmp='.';cout<<tmp<<" ";//cin>>tmp;mp[i]<<=1;mp[i]+=(tmp=='X');}cout<<endl;}//for(int i=0;i<n;i++)cout<<mp[i]<<endl;int ans=n*m;int mod=(1<<m)-1;for(int i=0; i<(1<<m); i++){int pre_choose=0;int now_choose=i;int effect;int cnt=0;for(int j=0; j<n; j++){effect=Get_Effect(now_choose,cnt)&mod;/*cout<<j+1;cout<<": pre_choose:"<<setw(3)<<pre_choose;cout<<" now_choose:"<<setw(3)<<now_choose;cout<<" effect:"<<setw(3)<<effect;cout<<" now_state:"<<setw(3)<<(mp[j]^pre_choose^effect);cout<<" mod:"<<setw(3)<<mod<<endl;*/int tmp=(mp[j]^pre_choose^effect);//cout<<"tmp:"<<tmp<<endl;pre_choose=now_choose; now_choose=tmp;}if(now_choose==0)cout<<"test:"<<hex<<i<<" "<<dec<<cnt<<endl;if(now_choose==0)ans=min(ans,cnt);}cout<<ans<<endl;return 0;
}int Get_Effect(int choose,int& cnt)
{int effect=0;for(int k=0; (1<<k)<=choose; k++){if((1<<k)&choose){effect^=(1<<(k-1));effect^=(1<<(k+0));effect^=(1<<(k+1));cnt++;}}return effect;
}
2016年第31届宁波市信息学竞赛复赛试题 D 射击相关推荐
- 绍兴市第十六届计算机复赛试题,绍兴市第十七届少儿信息学竞赛复赛试题
绍兴市第十七届少儿信息学竞赛复赛试题 (考试时间:150分钟) 一.题目一览 中文题目名称 英文题目名称 输入文件名 输出文件名 每个测试点时限 测试点数目 每个测试点分值 听歌识曲 song son ...
- 沙盘游戏(2017绍兴市第十五届少儿信息学竞赛复赛试题)
沙盘游戏 Ivy是如此地喜欢编程,以至于在面对游戏时也是如此.在沙盘游戏中有一个巨大的方形沙盘(长方形或者正方形),该沙盘被分隔成边长为1的小方格,每个小方格内有一个整数.沙盘玩家需要在沙盘中圈出一个 ...
- 2018年新生个人训练赛第十场(第29-30届宁波市信息学竞赛小学组)
问题 A: 幸运数字III [ 提交][ 状态][ 讨论版] 题目描述 小李非常喜欢数字4和7,看到一个数字他就想快速计算出因子里面分别有几个4和7,但是智商捉急的他总是要算很久,喜欢编程的你能够帮助 ...
- 2022 年合肥市经开区第七届青少年信息学竞赛 小学组试题题解
目录 第一题 车辆统计 第二题 直角三角形 第三题 质因数 第四题 采摘苹果 第一题 车辆统计
- 2022 年合肥市经开区第七届青少年信息学竞赛 小学组试题
一.题目概况 二.注意事项 1.务必看清题目,严格按照所要求的格式输入.输出. 2.在调试程序时请先使用题目中的示例数据,然后再自行设计多组测试数据进行 调试. 3.每题一般有 10 个测试点,测试有 ...
- 2016年蜀山区第十五届青少年信息学竞赛
2016年蜀山区第十五届青少年信息学竞赛 小学组试题 一.题目概况 题目名称 求差 生日 抓牛 工资 文件名
- 2016宁波计算机程序复赛,宁波第31届中小学生计算机程序设计竞赛复赛试题小学组.PDF...
宁波第31届中小学生计算机程序设计竞赛复赛试题小学组 宁波市第31 届中小学生计算机程序设计竞赛复赛试题(小学组) 宁波市第31 届中小学生计算机程序设计竞赛 复赛试题(小学组) 比赛时间:2016 ...
- 第29届宁波市中小学生计算机程序设计竞赛复赛名单公布,宁波市第23届中小学生计算机程序设计竞赛复赛试题(小学组)...
<宁波市第23届中小学生计算机程序设计竞赛复赛试题(小学组)>由会员分享,可在线阅读,更多相关<宁波市第23届中小学生计算机程序设计竞赛复赛试题(小学组)(7页珍藏版)>请在人 ...
- 合肥青少年信息学计算机竞赛试题,合肥市竞赛_27届合肥市信息学竞赛试题和答案_淘题吧...
Ⅰ 合肥市第二十七届青少年信息学(计算机)竞赛小学组答案 动态规划? Ⅱ 合肥市化学竞赛 这个我不知道啊,不过我的经验是实验题多做一些好,一些物质的性质掌握些好,不知道会不会有分析题出现,我参加的福建 ...
最新文章
- caffe学习(五):cifar-10数据集训练及测试(Ubuntu)
- Java7 ConcurrentHashMap详解
- vmware14/15 安装Ubuntu12.04 图文八步法
- sql 取汉字首字母
- php open gl,Open GL 资料 01
- 位运算在一类数组题中的用法 只出现一次的数字I
- Ubuntu20.04更新源步骤
- 微信小程序之表单验证
- 白鸦:我印象中的Keso
- js混淆还原工具_技术分享:几种常见的JavaScript混淆和反混淆工具分析实战【转】...
- 人脸关键点检测face_landmark
- DOS命令的英文全称
- 学会这27种编程语言,你还怕找不到女朋友?!那是要几个有几个!
- 【Scrum模式语言15】发布计划(Release Plan)
- 2018年9月份面试小记
- linux开放端口的两种方法
- [指南]上海逛街大全
- java共享经济项目分享_共享创业项目平台哪个好(分享5个共享创业项目)
- H5缓存机制浅析-移动端Web加载性能优化【干货】
- 仪表放大器放大倍数分析-运算放大器
热门文章
- C++ opencv模板匹配
- python编程基础:快速微服务框架指南:flask:1: 简介与Hello World
- 关于markdown的licens
- 2016猴年春节有感,androidframework开发面试
- 2023基于微信小程序的婚庆婚纱摄影预约平台(SSM+mysql)-JAVA.VUE(论文+开题报告+运行)
- 对古人“一命二运三风水,四积德五读书”的人生命运总结的理解
- rust石头墙几个c4_290多种常用艺术贴图素材合集 Gumroad – Julio Sillet 3D Art – All Texture Packs ......
- 微信暗黑版7.0.10真的要来了!你会用吗?
- 集成电路领域核心会议与期刊
- javascript---window.createPopup