首页 技术 正文
技术 2022年11月15日
0 收藏 837 点赞 4,721 浏览 4261 个字

2706: [SDOI2012]棋盘覆盖

Time Limit: 10 Sec  Memory Limit: 256 MB
Submit: 255  Solved: 77
[Submit][Status]

Description

在一个N*M个方格组成的棋盘内,有K个方格被称为特殊方格。我们要使用一组俄罗斯方块来覆盖这个棋盘,保证特殊方格不能被覆盖,非特殊方格只能被一个俄罗斯方块覆盖,求最多能容纳的俄罗斯方块的数量。已知有以下三组俄罗斯方块,一个棋盘可能用其中的某一组。 

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);
}
}
相关推荐
python开发_常用的python模块及安装方法
adodb:我们领导推荐的数据库连接组件bsddb3:BerkeleyDB的连接组件Cheetah-1.0:我比较喜欢这个版本的cheeta…
日期:2022-11-24 点赞:878 阅读:8,964
Educational Codeforces Round 11 C. Hard Process 二分
C. Hard Process题目连接:http://www.codeforces.com/contest/660/problem/CDes…
日期:2022-11-24 点赞:807 阅读:5,486
下载Ubuntn 17.04 内核源代码
zengkefu@server1:/usr/src$ uname -aLinux server1 4.10.0-19-generic #21…
日期:2022-11-24 点赞:569 阅读:6,331
可用Active Desktop Calendar V7.86 注册码序列号
可用Active Desktop Calendar V7.86 注册码序列号Name: www.greendown.cn Code: &nb…
日期:2022-11-24 点赞:733 阅读:6,114
Android调用系统相机、自定义相机、处理大图片
Android调用系统相机和自定义相机实例本博文主要是介绍了android上使用相机进行拍照并显示的两种方式,并且由于涉及到要把拍到的照片显…
日期:2022-11-24 点赞:512 阅读:7,747
Struts的使用
一、Struts2的获取  Struts的官方网站为:http://struts.apache.org/  下载完Struts2的jar包,…
日期:2022-11-24 点赞:671 阅读:4,781