bzoj 2706: [SDOI2012]棋盘覆盖 Dancing Link
2706: [SDOI2012]棋盘覆盖
Time Limit: 10 Sec Memory Limit: 256 MB
Submit: 255 Solved: 77
[Submit][Status]
Description
Input
第一行三个整数,N,M,K,和一个字符,type,为所用的俄罗斯方块组。
接下来K行每行两个整数,X,Y,表示第X行第Y列为特殊方格。
Output
一个整数,为所求的答案。
【样例输入1】
8 8 0 A
【样例输出1】
32
【样例输入2】
7 6 6 C
3 1
3 6
5 3
5 4
5 7
6 7
【样例输出2】
12
【数据范围】
|
测试点 |
N,M |
K |
type |
|
[1, 6] |
0 < N,M <= 100 |
0<=K<=N*M |
A |
|
[7, 12] |
N=M=2^L,0<L<=200000 |
K=1 |
B |
|
[13, 20] |
0<N,M<=11 |
0<=K<=N*M |
C |
第一组:二分图匹配
第二组:可以通过分治法证明ans=(n*n-1)/3
第三组:我用的是Dancing Link,但是不知道有没有网络流解法,如果用dancing link那么要注意如果当前答案等于(n*m-k)/3就强制退出。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
using namespace std;
namespace sec1
{
const int maxe=;
const int maxv=;
const int maxn=;
const int mov[][]={{,},{-,},{,-},{,}};
struct Edge
{
int np,val;
Edge *next;
}E[maxe],*V[maxv];
int tope=-;
bool bad[maxn][maxn];
void addedge(int x,int y)
{
E[++tope].np=y;
E[tope].next=V[x];
V[x]=&E[tope];
}
bool vis[maxn*maxn];
int ptr[maxn*maxn];
bool find(int now)
{
Edge *ne;
for (ne=V[now];ne;ne=ne->next)
{
if (vis[ne->np])continue;
vis[ne->np]=true;
if (!ptr[ne->np] || find(ptr[ne->np]))
{
ptr[ne->np]=now;
return true;
}
}
return false;
}
int main(int n,int m,int t)
{
int i,j,k,x,y;
for (i=;i<t;i++)
{
scanf("%d%d",&x,&y);
bad[x][y]=true;
}
for (i=;i<=n;i++)
{
for (j=;j<=m;j++)
{
if (bad[i][j] || ((i+j)&))continue;
for (k=;k<;k++)
{
if (i+mov[k][]> && i+mov[k][]<=n
&& j+mov[k][]> && j+mov[k][]<=m
&& !bad[i+mov[k][]][j+mov[k][]])
{
addedge(i*m+j,(i+mov[k][])*m+j+mov[k][]);
}
}
}
}
int ans=;
for (i=;i<=n;i++)
{
for (j=;j<=m;j++)
{
if ((i+j)%==)
{
memset(vis,,sizeof(vis));
ans+=find(i*m+j);
}
}
}
printf("%d\n",ans);
return ;
}
}
namespace sec2
{
const int maxn=;
int a[maxn];
long long b[maxn];
void main(const char* str)
{
int m=strlen(str);
for (int i=;i<m;i++)
a[(m-i-)/]=a[(m-i-)/]*+str[i]-'';
int n=(m-)/;
for (int i=;i<=n;i++)
for (int j=;j<=n;j++)
{
b[i+j]+=(long long)a[i]*a[j];
b[i+j+]+=b[i+j]/;
b[i+j]%=;
}
for (int i=;i<n*+;i++)
{
b[i+]+=b[i]/;
b[i]%=;
}
n=n*+;
while (!b[n])n--;
b[]--;
for (int i=n;i>=;i--)
{
b[i-]+=b[i]%*;
b[i]/=;
}
while (!b[n])n--;
printf("%lld",b[n]);
for (int i=n-;i>=;i--)
printf("%08lld",b[i]);
printf("\n");
}
}
namespace sec3//DLX
{
//{{{
const int maxn=;
const int maxd=maxn*maxn**;
const int mov[][]={{,},{-,},{,-},{,}};
const int inf=0x3f3f3f3f;
int L[maxd],R[maxd],D[maxd],U[maxd];
bool bad[maxn][maxn];
int tt[maxd];
int top[maxd];
int head[maxn*maxn];
int vec[];
int ans=,cnt=;
int topd=;
int anslim;
void Init_DLX(int l)
{
int now;
L[]=R[]=D[]=U[]=;
for (int i=;i<=l;i++)
{
now=++topd;
R[now]=head[];
L[now]=L[head[]];
U[now]=D[now]=now;
L[R[now]]=now;
R[L[now]]=now;
top[now]=i;
head[i]=now;
}
}
void Add_DLX(int *ss)
{
int now=++topd;
D[now]=head[];
U[now]=U[head[]];
L[now]=R[now]=now;
D[U[now]]=now;
U[D[now]]=now;
int h0=now;
while (~(*ss))
{
now=++topd;
D[now]=head[*ss];
U[now]=U[head[*ss]];
L[now]=L[h0];
R[now]=h0;
U[D[now]]=now;
D[U[now]]=now;
R[L[now]]=now;
L[R[now]]=now;
top[now]=*ss;
tt[*ss]++;
ss++;
}
}
void Cover(int c)
{
R[L[c]]=R[c];
L[R[c]]=L[c];
for (int i=D[c];i!=c;i=D[i])
{
for (int j=R[i];j!=i;j=R[j])
{
tt[top[j]]--;
U[D[j]]=U[j];
D[U[j]]=D[j];
}
}
}
void Resume(int c)
{
R[L[c]]=c;
L[R[c]]=c;
for (int i=D[c];i!=c;i=D[i])
{
for (int j=R[i];j!=i;j=R[j])
{
tt[top[j]]++;
U[D[j]]=D[U[j]]=j;
}
}
}
void Search_DLX(int tot)
{
ans=max(ans,tot);
if (ans==anslim)return;
int bst=inf,bstid;
bstid=R[head[]];
for (int i=R[head[]];i!=head[];i=R[i])
if (tt[top[i]] && tt[top[i]]<bst)
bst=tt[top[i]],bstid=top[i];
for (int i=D[head[bstid]];i!=head[bstid];i=D[i])
{
int k;
for (k=R[i];top[k];k=R[k]);
for (int j=R[k];j!=k;j=R[j])Cover(head[top[j]]);
Search_DLX(tot+);
for (int j=R[k];j!=k;j=R[j])Resume(head[top[j]]);
}
}
void main(int n,int m,int t)
{
int i,j,k1,k2;
vec[]=-;
int x,y;
for (i=;i<t;i++)
{
scanf("%d%d",&x,&y);
bad[x][y]=true;
}
anslim=(n*m-t)/;
Init_DLX((n+)*m);
for (i=;i<=n;i++)
{
for (j=;j<=m;j++)
{
if (bad[i][j])continue;
for (k1=;k1<;k1++)
{
if (i+mov[k1][]== || i+mov[k1][]==n+
|| j+mov[k1][]== || j+mov[k1][]==m+
|| bad[i+mov[k1][]][j+mov[k1][]])
continue;
for (k2=k1+;k2<;k2++)
{
if (i+mov[k2][]== || i+mov[k2][]==n+
|| j+mov[k2][]== || j+mov[k2][]==m+
|| bad[i+mov[k2][]][j+mov[k2][]])
continue;
vec[]=i*m+j;
vec[]=(i+mov[k2][])*m+j+mov[k2][];
vec[]=(i+mov[k1][])*m+j+mov[k1][];
Add_DLX(vec);
}
}
}
}
Search_DLX();
printf("%d\n",ans);
}
//}}}
}
char str[];
int main()
{
freopen("input.txt","r",stdin);
freopen("output.txt","w",stdout);
int n,m,t;
char type;
scanf("%s %d %d %c\n",str,&m,&t,&type);
if (type=='A')
{
sscanf(str,"%d",&n);
sec1::main(n,m,t);
}else if (type=='B')
{
sec2::main(str);
}else if (type=='C')
{
sscanf(str,"%d",&n);
sec3::main(n,m,t);
}
}
bzoj 2706: [SDOI2012]棋盘覆盖 Dancing Link的更多相关文章
- BZOJ2706 : [SDOI2012]棋盘覆盖
A类数据: 将棋盘黑白染色,相邻的点之间连边,求出二分图最大匹配即可. B类数据: 答案为$\lfloor\frac{n^2-1}{3}\rfloor$,用FFT加速计算即可,时间复杂度$O(L\lo ...
- hdu 1426 Sudoku Killer ( Dancing Link 精确覆盖 )
利用 Dancing Link 来解数独 详细的能够看 lrj 的训练指南 和 < Dancing Links 在搜索中的应用 >这篇论文 Dancing Link 来求解数独 , ...
- dancing link模板
#include<cstdio> #include<iostream> #include<cstring> #include<algorithm> #i ...
- dancing link 学习资源导航+心得
dancing link简直是求解数独的神器,NOIP2009最后一题靶形数独,DFS 各种改变搜索顺序 都没法过,最后还是用了卡时过得.用dancing link写,秒杀所有数据,总时间才400ms ...
- 【Dancing Link专题】解题报告
DLX用于优化精确覆盖问题,由于普通的DFS暴力搜索会超时,DLX是一个很强有力的优化手段,其实DLX的原理很简单,就是利用十字链表的快速删除和恢复特点,在DFS时删除一些行和列以减小查找规模,使得搜 ...
- 「CH6801」棋盘覆盖
「CH6801」棋盘覆盖 传送门 考虑将棋盘黑白染色,两个都无障碍的相邻的点之间连边,边的容量都为1,然后就求一次最大匹配即可 参考代码: #include <cstring> #incl ...
- Dancing Link 详解(转载)
Dancing Link详解: http://www.cnblogs.com/grenet/p/3145800.html Dancing Link求解数独: http://www.cnblogs.co ...
- hustoj 1017 - Exact cover dancing link
1017 - Exact cover Time Limit: 15s Memory Limit: 128MB Special Judge Submissions: 5851 Solved: 3092 ...
- NYOJ 45 棋盘覆盖
棋盘覆盖 水题,题不难,找公式难 import java.math.BigInteger; import java.util.Scanner; public class Main { public s ...
随机推荐
- BeagleBone Black Linux驱动程序开发入门(0): 开发环境
搭建arm-linux交叉编译环境的教程有很多,这里只作简要说明.Host宿主机是Ubuntu10.04,我把它装在Windows XP的VirtualBox虚拟机中,这样相当于一台主机有两个操作系统 ...
- Java基础知识强化之IO流笔记38:字符流缓冲流之BufferedWriter / BufferedReader使用
1. 字符流缓冲流: 字符流为了高效读写,也提供了对应的字符缓冲流. BufferedWriter:字符缓冲输出流 BufferedReader:字符缓冲输入流 2. BufferedWriter使用 ...
- 对于top.ascx里面可以不可以放置css的文件进行一个讲解
今天遇到一个这样的问题就是把网站上面的flash做的导航栏和图片动画替换成html+css的代码,然而asp.net里面的页面又是xx.ascx的文件夹,当时我就晕了不知道改如何去下手,我就把里面的c ...
- zTree判断是否为父节点
var treeObj = $.fn.zTree.getZTreeObj("tree"); var nodes = treeObj.getSelectedNodes(); if(t ...
- 重写equals方法的约定
1. 什么时候需要重写Object.equals方法 如果类具有自己特有的“逻辑相等”概念(不同于对象等同的概念),而且超类还没有覆盖equals以实现期望的行为,这时我们就需要覆盖equals方法. ...
- SQLServe错误整理
1. sql拒绝访问?提示SQL Serve不存在或访问被拒绝 (SQL Server does not exist or access denied.) (A) 1:你如果是独立上网的请把21端口打 ...
- HDU-1018(简单数学)
Big Number Problem Description In many applications very large integers numbers are required. Some o ...
- 【转】浅谈Java中的hashcode方法(这个demo可以多看看)
浅谈Java中的hashcode方法 哈希表这个数据结构想必大多数人都不陌生,而且在很多地方都会利用到hash表来提高查找效率.在Java的Object类中有一个方法: public native i ...
- netMVC 搭建Ucenter 同步登陆退出discuz
先看一下效果
- 学习笔记_Java get和post区别(转载_GET一般用于获取/查询资源信息,而POST一般用于更新资源信息)
转载自:[hyddd(http://www.cnblogs.com/hyddd/)] 总结一下, Get是向服务器发索取数据的一种请求 而Post是向服务器提交数据的一种请求,在F ...