20180520模拟赛T3——chess
【问题描述】
小美很喜欢下象棋。
而且她特别喜欢象棋中的马。
她觉得马的跳跃方式很独特。(以日字格的方式跳跃)
小芳给了小美一张很大的棋盘,这个棋盘是一个无穷的笛卡尔坐标。
一开始\(time=0\)的时候,马在原点。每个时刻马都跳一步。
可是这个坐标图有点残缺,有几个点是不能跳到的。
然后小美很好奇在\(time=[0,K]\)中,马能跳到多少个不同的格子。
【输入格式】
从文件chess.in
中读入数据。
第一行两个数K,n
表示时间上限和残缺的点的数量。
接下来n行,每行一个坐标 xi,yi
表示一个残缺点的坐标。
【输出格式】
输出到文件chess.out
中。
第一行输出一个数字表示答案。由于这个数字会很大,你需要输出他模 1000000007 。
【样例输入】
1 0
【样例输出】
9
【样例输入】
2 7
-1 2
1 2
2 1
2 -1
1 -2
-1 -2
-2 -1
【样例输出】
9
【数据规模】
对于\(30\%\)的数据\(K\le 500\)。
对于\(100\%\)的数据\(0\le K \le 10^{18}, 0\le n\le 440, |xi|\le10, |yi|\le 10\)。
【来源】
题解
一道神奇的乱搞题。
首先,对于一个oier,最基本的技能是暴力,于是我们先用bfs打一个暴力(代码下面会有)。
于是就拿到了37分的好成绩。
但是除了大暴力,我们似乎并没有什么路可走——因为情况非常复杂。
那么这题为什么这么复杂?
因为有这句话:可是这个坐标图有点残缺,有几个点是不能跳到的。
于是我们想到简化:那这句话不在会怎么样?
我们发现一时找不出规律,但我们可以打张表。
#include <cstdio>
#include <queue>
using namespace std;
int mp[2003][2003];
int ans[6000];//ans[i]:第i步所到新到达的地方
int dirx[] = {1, 1, -1, -1, 2, 2, -2, -2};
int diry[] = {2, -2, 2, -2, 1, -1, 1, -1};
struct sxd
{
int x, y;
};
queue<sxd> Q;
int n;
long long k;
long long cnt;
inline void bfs(int x, int y)
{
mp[x][y] = 1;
Q.push((sxd){x, y});
while(!Q.empty())
{
sxd tmp = Q.front();
Q.pop();
ans[mp[tmp.x][tmp.y]]++;
if(mp[tmp.x][tmp.y] > 70)
break;
for(int i = 0; i < 8; ++i)
{
int tx = tmp.x + dirx[i];
int ty = tmp.y + diry[i];
if(mp[tx][ty]) continue;
mp[tx][ty] = mp[tmp.x][tmp.y] + 1;
Q.push((sxd){tx, ty});
}
}
}
int main()
{
bfs(1001, 1001);
for(int i = 1; i <= 60; ++i)
printf("%d,", ans[i]);
return 0;
}
运行结果:
1,8,32,68,96,120,148,176,204,232,260,288,316,344,372,400,428,456,484,512,540,568,596,624,652,680,708,736,764,792,820,848,876,904,932,960,988,1016,1044,1072,1100,1128,1156,1184,1212,1240,1268,1296,1324,1352,1380,1408,1436,1464,1492,1520,1548,1576,1604,1632,
发现了什么?(并没有发现什么)到了后面项,该数列竟趋向于一个等差数列!
把printf("%d,", ans[i]);
改成printf("%d,", ans[i+1]-ans[i]);
会更清晰:
7,24,36,28,24,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,
然后我们就可以大胆猜想了……
我们发现数据规模中\(|xi|, |yi|\)的值很小,是不是这样就不怎么会影响等差数列的波动幅度?
于是我们需要验证一下
//前面只是把if(mp[tmp.x][tmp.y] > 70)改成了if(mp[tmp.x][tmp.y] > 200)
int main()
{
bfs(1001, 1001);
cin >> n;
for(int i = 1, x, y; i <= n; ++i)
{
cin >> x >> y;
x += 1001;
y += 1001;
mp[x][y] = 1;//这样做还是挺妙的,把残缺坐标直接看成已访问
}
for(int i = 1; i <= 150; ++i)//输出多一些,让结论更可信
printf("%d,", ans[i+1] - ans[i]);
return 0;
}
随便造组数据验证一下:
8
2 3
1 2
2 1
5 6
-1 -2
-2 -1
-3 -4
-3 -2
输出
7,24,36,28,24,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,
经过多次验证,我们就可以很方便地想到正解:先暴力搜索几步(似乎都是选择500步的),然后用等差数列直接求出答案。
于是代码如下
//前面的bfs都差不多,就在写一遍了。
signed main()
{
fin >> k >> n;//由于当时是模拟赛所以用了文件流
for(int i = 1, x, y; i <= n; ++i)
{
fin >> x >> y;
x += 1001;
y += 1001;
mp[x][y] = 1;
}
bfs(1001, 1001);
if(k < 500)
{
for(int i = 1; i <= k+1; ++i)
cnt = (cnt+ans[i])%mod;
fout << cnt << endl;
}
else
{
long long inc = ans[500] - ans[499];//等差数列的公差
k -= 498;
k %= mod;
for(int i = 0; i <= 499; ++i)
cnt = (cnt+ans[i])%mod;
fout << (((k*ans[500]%mod+cnt)%mod+(k*(k-1)>>1)%mod*inc%mod)%mod+mod)%mod << endl;
}
return 0;
}
最后,恭喜你打出了一道tourist当场也没打出来的题。
20180520模拟赛T3——chess的更多相关文章
- 体育成绩统计——20180801模拟赛T3
体育成绩统计 / Score 题目描述 正所谓“无体育,不清华”.为了更好地督促同学们进行体育锻炼,更加科学地对同学们进行评价,五道口体校的老师们在体育成绩的考核上可谓是煞费苦心.然而每到学期期末时, ...
- 20161005 NOIP 模拟赛 T3 解题报告
subset 3.1 题目描述 一开始你有一个空集,集合可以出现重复元素,然后有 Q 个操作 1. add s 在集合中加入数字 s. 2. del s 在集合中删除数字 s.保证 s 存在 3. c ...
- ztz11的noip模拟赛T3:评分系统
代码: #include<iostream> #include<cstdio> #include<cstring> #include<algorithm> ...
- 20180711模拟赛T3——聚变
文件名: fusion 题目类型: 传统题 时间限制: 3秒 内存限制: 256MB 编译优化: 无 题目描述 知名科学家小A在2118年在计算机上实现了模拟聚变的过程. 我们将她研究的过程简化. 核 ...
- 4.26 省选模拟赛 T3 状压dp 差分求答案
LINK:T3 比较好的题目 考试的时候被毒瘤的T2给搞的心态爆炸 这道题连正解的思路都没有想到. 一看到题求删除点的最少个 可以使得不连通. 瞬间想到最小割 发现对于10分直接跑最小割即可. 不过想 ...
- NOIP欢乐模拟赛 T3 解题报告
3.小澳的葫芦 (calabash.cpp/c/pas) [题目描述] 小澳最喜欢的歌曲就是<葫芦娃>. 一日表演唱歌,他尽了洪荒之力,唱响心中圣歌. 随之,小澳进入了葫芦世界. 葫芦世界 ...
- 字符串模拟赛T3
只看我的做法就够了 #include<iostream> #include<cstdio> #include<string> #include<cstring ...
- 神奇的NOIP模拟赛 T3 LGTB 玩THD
LGTB 玩THD LGTB 最近在玩一个类似DOTA 的游戏名叫THD有一天他在守一座塔,对面的N 个小兵排成一列从近到远站在塔前面每个小兵有一定的血量hi,杀死后有一定的金钱gi每一秒,他都可以攻 ...
- [模拟赛] T3 Exploit
Description 4X概念体系,是指在PC战略游戏中一种相当普及和成熟的系统概念,得名自4个同样以"EX"为开头的英语单词. eXplore(探索) eXpand(拓张与发展 ...
随机推荐
- asp.net core 系列之允许跨域访问-1(Enable Cross-Origin Requests:CORS)
接上篇的允许跨域 4.CORS 策略(Policy)的选项 这里讲解Policy可以设置的选项: 设置允许的访问源 设置允许的HTTP methods 设置允许的请求头(request header) ...
- C# 调用Access数据库关于like模糊查询的写法
在access查询视图中要使用"*"做模糊匹配,但是在程序中要用%来匹配.在access中:NEIBUBH like '*1234*'在程序中:NEIBUBH like '%123 ...
- Echarts X轴多项百分比的展示
app.title = '堆叠柱状图'; option = { tooltip : { trigger: 'axis', axisPointer : { // 坐标轴指示器,坐标轴触发有效 type ...
- Gearman介绍、原理分析、实践改进
gearman是什么? 它是分布式的程序调用框架,可完成跨语言的相互调用,适合在后台运行工作任务.最初是2005年perl版本,2008年发布C/C++版本.目前大部分源码都是(Gearmand服务j ...
- tqdm()与set_description()的用法
pbar=tqdm(range(55156))for i in pbar: # print(i) a=464443161*845113131 pbar.set_description("tr ...
- Linux环境:VMware下windows虚拟机与linux主机进行文件共享的方法
操作主要分两大步骤: 一.是对主机进行配置: 二.是在虚拟机上直接连接共享目录. 一.主机配置 1.打开VMware虚拟机,双击需要进行文件共享的虚拟机.如下图,双击CentOS 64位(以linux ...
- 前端1-----CSS颜色属性,字体文本和背景属性,边框属性,margin和padding,盒模型,行内块转换,浮动,三大定位
前端1-----CSS颜色属性,字体文本和背景属性,边框属性,margin和padding,盒模型,行内块转换,浮动,三大定位 一丶css选择器的优先级 行内 > id选择器 > 类选择器 ...
- Matlab访问者模式
访问者(Visitor)模式的定义:将作用于某种数据结构中的各元素的操作分离出来封装成独立的类,使其在不改变数据结构的前提下可以添加作用于这些元素的新的操作,为数据结构中的每个元素提供多种访问方式.它 ...
- OpenGL 中的三维纹理操作
#define _CRT_SECURE_NO_WARNINGS #include <gl/glut.h> #include <stdio.h> #include <std ...
- pandas-18 reindex用法
pandas-18 reindex用法 pandas中的reindex方法可以为series和dataframe添加或者删除索引. 方法:serise.reindex().dataframe.rein ...