传送门

Description

耳熟能详,就不多说了

Solution

对于一个不会推式子的蒟蒻,如何在考场优雅地通过此题

  1. 手玩样例,发现对于 \(n=1\) , \(ans=2^m\) 。对于 \(n=2\) , \(ans=4\times 3^{m-1}\) 。或者干脆打出 \(n,m\le 3\) 的表

  2. 肉眼观察法,发现似乎有 \(f(n,m+1)=3f(n,m)\),但这并不是正确的,但如果你仅仅是这么认为了,你仍然能够获得很多分数

  3. 想结论,都是特别特别显然的那种:

  • \(f(n,m)=f(m,n)\) ,因而只要考虑 \(n\le m\) 的情况

  • 因为每步向右或向下,所以可按照步骤,把图分成一条条从左下到右上的斜线,对于单个格子进行考虑,发现每条斜线上的数单调不增(所以呢,你就可以通过枚举每条斜线在哪个位置开始变为\(0\)就可以了,简单打表)

  • 为了检验图的正确性,我们还需要发掘合法填数方式的更多性质:

    考虑怎样造成不合法,存在两条路径,它们在某个位置不合法了,那么它们之前路径对应的01串相同,且上一个位置相同,在不合法的这一步中,大的路径走了 \(0\) ,小的路径走了 \(1\) 。

    这启发我们,对于一张合法的图,如果某个点,存在两条到达它的路径对应相同的01串,那么它的后继相同,我们令这样的点叫\(A\)点,一个点是\(A\)点当且仅当它的前驱中有A点或者它的前驱的数相同

  1. 有了这么多的性质,我们发现其实可以打表拿很多分了,于是开始愉快地搜索,按照斜线一条条地搜,边搜边更新当前图的点中\(A\)类的点,同时,每条斜线上只有 \(0\) 和 \(1\) 的交界处可能导致不合法,判断一下它的上一个点是否是\(A\)类点就可以了
  2. 打出表了,发现结论 \(f(n,m+1)=3f(n,m),m>n\) !于是就很开心地过了
  3. 这个搜索是真的快,极限数据 \(n=8,m=9\) 都能在 \(0.6s\) 内过去,所以就连表都懒得打了,直接暴力就行了

Code 

#include<bits/stdc++.h>
#define ll long long
#define db double
#define reg register
using namespace std;
#define dbg1(x) cerr<<#x<<'='<<(x)<<' '
#define dbg2(x) cerr<<#x<<'='<<(x)<<'\n'
#define dbg3(x) cerr<<#x<<'\n'
inline int read()
{
int x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=(x<<3)+(x<<1)+ch-'0';ch=getchar();}
return x*f;
}
const int P=1e9+7;
int Add(int x,int y){return (x+y)%P;}
int Mul(int x,int y){return (1ll*x*y)%P;}
int fp(int x,int y){int r=1;if(y>0)for(;y;y>>=1,x=Mul(x,x))if(y&1)r=Mul(r,x);return r;}
int n,m;ll ans=0;
int Nm[20],X[20][20],Y[20][20];
bool mk[10][10],mp[10][10];
inline void getmk(int now)
{
int i,j;
for(i=X[now][1],j=Y[now][1];i&&j<=m;--i,++j)
if(i>1&&j>1)mk[i][j]=(mk[i-1][j]|mk[i][j-1]|(mp[i][j-1]==mp[i-1][j]));
}
void dfs(int now)
{
int i,j,p=Nm[now];getmk(now-1);
for(i=0;i<=p;++i)
{
if(i)mp[X[now][i]][Y[now][i]]=true;
if((i==0||i==p)||(i>0&&i<p&&!mk[X[now][i]-1][Y[now][i]]))
if(now+1==n+m)++ans;else dfs(now+1);
}
for(i=1;i<=p;++i)mp[X[now][i]][Y[now][i]]=0;
}
int main()
{
freopen("game.in","r",stdin);
freopen("game.out","w",stdout);
n=read();m=read();
if(n>m)swap(n,m);
if(n==1)return 0*printf("%d\n",fp(2,m));
int c=max(0,min(m-n,m-n-1));m-=c;
reg int i,j;
for(i=1;i<=n;++i)Nm[i]=i;
for(i=n+1;i<m;++i)Nm[i]=n;
for(i=m;i<n+m;++i)Nm[i]=n+m-i;
for(i=1;i<=n;++i)X[i][1]=i,Y[i][1]=1;
for(i=n+1;i<n+m;++i)X[i][1]=n,Y[i][1]=i-n+1;
for(i=1;i<n+m;++i)for(j=2;j<=Nm[i];++j)X[i][j]=X[i][j-1]-1,Y[i][j]=Y[i][j-1]+1;
dfs(1);printf("%lld\n",Mul(ans,fp(3,c)));
}

Blog来自PaperCloud,未经允许,请勿转载,TKS!

[Noip2018]填数游戏的更多相关文章

  1. NOIP2018 填数游戏 搜索、DP

    LOJ 感觉这个题十分好玩于是诈尸更博.一年之前的做题心得只有这道题还记得清楚-- 设输入为\(n,m\)时的答案为\(f(n,m)\),首先\(f(n,m)=f(m,n)\)所以接下来默认\(n \ ...

  2. 【题解】NOIP2018 填数游戏

    题目戳我 \(\text{Solution:}\) 题目标签是\(dp,\)但是纯暴力打表找规律可以有\(65\)分. 首先是对于\(O(2^{nm}*nm)\)的暴力搜索,显然都会. 考虑几条性质: ...

  3. 【比赛】NOIP2018 填数游戏

    打表找规律.... #include<bits/stdc++.h> #define ui unsigned int #define ll long long #define db doub ...

  4. @NOIP2018 - D2T2@ 填数游戏

    目录 @题目描述@ @题解@ @代码@ @题目描述@ 小 D 特别喜欢玩游戏.这一天,他在玩一款填数游戏. 这个填数游戏的棋盘是一个 n×m 的矩形表格.玩家需要在表格的每个格子中填入一个数字(数字 ...

  5. 【逆向笔记】2017年全国大学生信息安全竞赛 Reverse 填数游戏

    2017年全国大学生信息安全竞赛 Reverse 填数游戏 起因是吾爱破解大手发的解题思路,觉得题挺有意思的,就找来学习学习 这是i春秋的下载链接 http://static2.ichunqiu.co ...

  6. luogu P5023 填数游戏

    luogu loj 被这道题送退役了 题是挺有趣的,然而可能讨论比较麻烦,肝了2h 又自闭了,鉴于CSP在即,就只能先写个打表题解了 下面令\(n<m\),首先\(n=1\)时答案为\(2^m\ ...

  7. JZOJ5965【NOIP2018提高组D2T2】填数游戏

    题目 作为NOIP2018的题目,我觉得不需要把题目贴出来了. 大意就是,在一个n∗mn*mn∗m的010101矩阵中,从左上角到右下角的路径中,对于任意的两条,上面的那条小于下面的那条.问满足这样的 ...

  8. NOIP2018 Day2T2 填数游戏

    下面先给出大家都用的打表大法: 首先我们可以发现 \(n \le 3\) 的情况有 \(65pts\),而 \(n\) 这么小,打一下表何乐而不为呢?于是我写了一个爆枚每个位置再 \(check\) ...

  9. UOJ#440. 【NOIP2018】填数游戏 动态规划

    原文链接www.cnblogs.com/zhouzhendong/p/UOJ440.html 前言 菜鸡选手到省选了才做联赛题. 题解 首先我们分析一下性质: 1. 假如一个格子是 0,那么它的右上角 ...

随机推荐

  1. js中的方法如何传入多个参数

    js中的方法如何传入多个参数 $(function () { let parameter1 = 1; let parameter2 = 'Hello World'; let parameter3 = ...

  2. sizeof()计算结构体的大小

    简要说明:结构体成员按照定义时的顺序依次存储在连续的内存空间,但是结构体的大小并不是简单的把所有成员大小相加,而是遵循一定的规则,需要考虑到系统在存储结构体变量时的地址对齐问题. 一.没有成员的结构体 ...

  3. 一个 Github 上使用 HttpClient 的 Sample

    地址:https://github.com/MikeWasson/HttpClientSample 截图: 直接贴代码了: 服务端: [RoutePrefix("api/products&q ...

  4. Oracle高危安全漏洞:具有查询权限用户可绕开安全限制进行数据修改

    数据库版本 11.2.0.* 检查数据库是否存在此bug的脚本: Oracle用户执行此脚本 #!/bin/bash # Usage: 检查ORACLE数据库是否存在高危安全漏洞(具有查询权限用户可绕 ...

  5. react+umi+netcore+signalR BS和客户端设备 简单通讯

    微信扫码登录工作用 仅作记录 扫码访问服务器地址 实现扫码服务器地址通讯中断设备解锁 采用signalR 双向异步通知中断 创建控制器 ChatController 注入集线器上下文 IHubCont ...

  6. loadrunner11 您不具有该 Vuser 类型的许可证. 请与 HP Software 联系以更新许可证.

    您不具有该 Vuser 类型的许可证. 请与 HP Software 联系以更新许可证. 在loadrunner11 执行发生报错: 打开loadrunner软件首页,点击配置-->loadru ...

  7. H5页面基础元素

    H5页面结构元素示例 <!DOCTYPE html> <html lang="zh"> <head> <meta charset=&quo ...

  8. Laravel集合的简单理解

    本篇文章给大家带来的内容是关于Laravel集合的简单理解,有一定的参考价值,有需要的朋友可以参考一下,希望对你有所帮助. 前言 集合通过 Illuminate\Database\Eloquent\C ...

  9. python高级编程——网络编程(三)

    TCP和并发服务器 与UDP不同的是,他是一个面向连接的,可靠的数据传输协议 TCP通信比较复杂 先写一个TCP服务器,一般步骤如下: 1.首先是要创建一个socket套接字:socket() 2.服 ...

  10. javascript format 字符串 函数

    函数实现如下: function format(string) { var args = arguments; var pattern = new RegExp("%([1-" + ...