solution:

首先我们根据一条路径上不能有两个相同颜色的格子可以得出:

对于两个格子 $ (x_1 , y_1 ) $ 和 $ (x_2 , y_2 ) $ 必须满足:

$ x_1<x_2 and y_1>y_2 $

$ x_1>x_2 and y_1<y_2 $

所以我们可以据此剪枝,但直接暴搜肯定会超时,我们肯定还有技巧:

  1. 根据上面的剪枝我们发现将表格以(1,1) -> (n,n) -> (1,2) -> (2,1) -> (n,n-1) -> (n-1,n). . .的顺序枚举速度会快很多

  2. 现在,我们把初始棋盘中没有出现过的颜色称作自由颜色。如果我们有两个自由颜色: 1 和 2 .假设我们找到了一个可行的最终棋盘,然后把所有的 1 换成 2 ,所有的 2 换成 1 。容易发现得到的棋盘依然是可行的。

    我们把自由颜色排序(随便怎么排),如果我们当前没有用过第 i 个自由颜色,那么我们就不准碰第 i+1 个自由颜色。到最后计算结果的时候,如果我们用了 x 个自由颜色,而总共有 y 个自由颜色,那么这个局面对答案的贡献也就是 y 个数中去取 x 个组成有序排列的数目。

code:

#include<iostream>
#include<cstdio>
#include<iomanip>
#include<algorithm>
#include<cstring>
#include<cstdlib>
#include<ctime>
#include<cmath>
#include<vector>
#include<queue>
#include<map>
#include<set> #define ll long long
#define db double
#define inf 0x7fffffff
#define rg register int
#define mod 1000000007
#define end {puts("0");return 0;} using namespace std; struct su{
int x,y;
}b[13],c[13],d[11][11]; ll ans;
int n,m,l,k,ti,top,sss;
int se[11],to[11];
int tot[11];
int P[11];
int a[10][10];
int ss[10][10];
bool s[10][10]; inline int qr(){
char ch;
while((ch=getchar())<'0'||ch>'9');
int res=ch^48;
while((ch=getchar())>='0'&&ch<='9')
res=res*10+(ch^48);
return res;
} inline void add(int t,int x,int y){
d[t][++tot[t]].x=x;
d[t][tot[t]].y=y;
} inline bool check(int i,int x,int y){
for(rg j=1,p,q;j<=tot[i];++j){
p=d[i][j].x;q=d[i][j].y;
if(x>=p&&y>=q)return 0;
if(x<=p&&y<=q)return 0;
}return 1;
} inline void dfs(int t){
if(t>n*m){
ans+=P[to[0]+sss-k];
return ;
}
rg x=b[t].x,y=b[t].y;
if(s[x][y]){dfs(t+1);return ;}
for(rg i=1;i<=to[0];++i){
if(check(i,x,y)){
add(i,x,y);
ss[x][y]=i;
dfs(t+1);
--tot[i];
}
}
if(to[0]==k)return ;
add(++to[0],x,y);
ss[x][y]=to[0];
dfs(t+1);
tot[to[0]]=0;--to[0];
return ;
} inline void bfs(){
for(rg o=1,i=0,j=1;o<=l;++o){
c[o].x=((i==n)?i:++i);
c[o].y=((i>=n)?j++:j);
}
for(rg o=0,r,i,j;o<l;++o){
r=o&1?l-o/2:o/2+1;
i=c[r].x;j=c[r].y;
for(;i&&j<=m;--i,++j)
b[++top].x=i,b[top].y=j;
}
} int main(){
//freopen("board.in","r",stdin);
//freopen("board.out","w",stdout);
n=qr(),m=qr(),k=qr();
if((l=n+m-1)>k) end;
for(rg i=1;i<=n;++i)
for(rg j=1;j<=m;++j){
ti=a[i][j]=qr();
if(ti){
s[i][j]=1;
if(se[ti]){
ti=se[ti];
ss[i][j]=ti;
}
else{
ti=se[ti]=++to[0];
to[ti]=a[i][j];
ss[i][j]=ti;
}
if(!check(ti,i,j)){
puts("0");
return 0;
}
add(ti,i,j);
}
}
sss=k-to[0];P[0]=1;
for(rg i=0;i<sss;++i)
P[i+1]=P[i]*(sss-i);
if(l==k){
printf("%d\n",P[sss]);
return 0;
}
top=0; bfs(); dfs(1);
printf("%lld\n",ans%mod);
return 0;
}

CF293B 方格(带技巧的搜索)的更多相关文章

  1. 解决eclipse中自带的maven搜索不到非本地第三方包问题

     解决eclipse中自带的maven搜索不到非本地第三方包问题   版权声明:本文为博主原创文章,未经博主允许不得转载. 最近使用eclipse中的maven插件时发现,在pom.xml文件中添加第 ...

  2. Vim实用技巧系列 - 搜索

    最近发现了一个很好的VIM资源,best of vim tips, 展示了一系列很有用的vim 技巧.博主会逐个翻译介绍这些技巧. 来源: http://rayninfo.co.uk/vimtips. ...

  3. 高效上网教程---资源软件搜索技巧(搜索好用软件或者app去哪些网站)

    高效上网教程---资源软件搜索技巧(搜索好用软件或者app去哪些网站) 一.总结 一句话总结:查看下面这些网站用户推荐的 知乎:比如 小众软件 site:zhihu.com 简书:查看你需要的用户推荐 ...

  4. 为何windows自带的文件搜索这么慢,而Everything的这么快

    为何windows自带的文件搜索这么慢,而Everything的这么快 摘自:http://blog.sina.com.cn/s/blog_9f0cf4ed0102wvkq.html (2016-07 ...

  5. 开发移动端web应用, 使用手机自带键盘的搜索按钮

    很多时候在移动端的web页面中, 需要使用搜索功能, 然而页面中并没有太多的空间来放置一个像pc端上那样的搜索按钮, 这时候就需要借用手机输入法自带的搜索按钮来实现点击搜索 虽然不是什么大的功能, 但 ...

  6. 移动端 input 获取焦点后弹出带enter(类似于搜索,确定,前往)键盘,以及隐藏系统键盘

    一:调出系统带回车键的键盘 在项目中经常有输入框,当输入完成后点击确定执行相应的动作.但是有些设计没有确定或者搜索按钮,这就需要调用系统键盘,点击系统键盘的确定后执行相应动作. 但是单纯的input是 ...

  7. 【Luogu】【关卡2-9】带有技巧的搜索(2017年10月)

    任务说明:这里的搜索不仅包含了dfs和bfs,还包括剪枝.记录等技巧以加快速度. [USACO06FEB]数字三角形Backward Digit Su… 滑雪 吃奶酪 靶形数独 P1118 [USAC ...

  8. jQuery带tab切换搜索框样式代码

    效果体验:http://hovertree.com/texiao/jquery/23/ 代码如下,保存到HTML文件也可以查看效果: <!DOCTYPE html> <html la ...

  9. Docker安装带中文全文搜索插件zhparser的Postgresql数据库

    上一篇讲了在已经安装了PG数据库的情况下,安装全文搜索插件zhparser遇到的问题.在一个全新的环境中安装带有全文搜索插件zhparser的PG数据库,可以使用已经做好的Docker镜像,在安装的过 ...

随机推荐

  1. 20135220谈愈敏Linux Book_5

    第五章 系统调用 内核提供了用户进程与内核进行交互的一组接口. 应用程序发出请求->内核负责满足 目的:保证系统稳定可靠 5.1 与内核通信 系统调用在用户空间进程和硬件设备之间添加了一个中间层 ...

  2. 2017-2018 第一学期201623班《程序设计与数据结构》-第5&6周作业问题总结

    一.作业内容 第5周作业 http://www.cnblogs.com/rocedu/p/7484252.html#WEEK05 第6周作业 http://www.cnblogs.com/rocedu ...

  3. php插入中文数据到MySQL乱码

    事情是这样的:我在本地的测试成功了,放到服务器测试,发现服务器的数据库里的中文竟然乱码了. 我进行了以下几步基本的做法: PHP文件改为utf-8的格式. 加入header("Content ...

  4. Apache ActiveMQ 学习一

    Apache ActiveMQ 5.8.0 Java 7 support (compiled with jdk6 and validated with jdk7) apache-activemq-5. ...

  5. 插入排序的C、C++实现

    一.插入排序 有一个已经有序的数据序列,要求在这个已经排好的数据序列中插入一个数,但要求插入后此数据序列仍然有序,这个时候就要用到一种新的排序方法--插入排序法,插入排序的基本操作就是将一个数据插入到 ...

  6. BroadcastReceiver介绍

    参考资料 : 基础总结篇之五:BroadcastReceiver应用详解 BroadcastReceiver用于接收广播信息,可以通过sendBroadcast等方法进行发送.sendBroadcas ...

  7. BOM之navigator对象和用户代理检测

    前面的话 navigator对象现在已经成为识别客户端浏览器的事实标准,navigator对象是所有支持javascript的浏览器所共有的.本文将详细介绍navigator对象和用户代理检测 属性 ...

  8. std::string 字符串切割

    在很多字符串类库里都实现了split函数.不过在std里没有实现.在这里拿出几个: 1. 用单字符作为分隔 #include <string> #include <vector> ...

  9. ST算法详解

    ST算法详解 Coded by Jelly_Goat. All rights reserved. 这个主要是说ST表的. 首先了解一下ST表是什么. 先来一个老套的情景带入. (假设所有的题目都是1s ...

  10. SP4487 GSS6 - Can you answer these queries VI

    题目大意 给出一个由N个整数组成的序列A,你需要应用M个操作: I p x 在 p  处插入插入一个元素 x D p 删除 p 处的一个元素 R p x 修改 p 处元素的值为 x Q l r 查询一 ...