bzoj3336 Uva10572 Black and White
题目描述:

数据范围:2<=n,m<=8
题解:
很明显需要状压。但是怎么压不知道,压什么不知道。
然后从条件下手。
条件1要求黑色在一起白色在一起,记录轮廓线很容易做到。
条件2要求不能出现$2*2$的同色方格。我们还需要再记录当前位置的左上角。
所以这道题的轮廓线长这样。

丑图。
我们需要确定一个顺序记录哪几块互相联通。由于轮廓线奇特的形状我决定这样标号。

如果编号相同但是并不互相联通我们可以知道他俩不同颜色。
为了颜色我们决定记录某个块的颜色,这样可以得到所有颜色。
于是这道题表中存的就是$1$号颜色+所有状态。
为了方便调试我用了十进制。
每次调用时都要解压,处理后压缩放回去。
由于第一行和第一列找不到长这样的轮廓线,我们可以搜出第一行所有状态,处理第一列时直接枚举黑色/白色。
接下来就是精彩的特判环节。
(这一部分针对处于中心部位的一干普通点)
以填黑色为例。
如果这里不能填黑:
1.输入要求白色。
2.拐角处已经有三个黑块。
3.要考虑到上图中红块填上后$5$号块就不再与不定颜色相邻,我们不能把$5$号块憋死我们要判断$5$号是否有与之联通的好朋友在轮廓线上。
类似围棋中的气。
如果没有而且$5$号是白的,那么就不能填黑!
等等好像是错的。
如果红块已经到$(n,m-1)$或者是$(n,m)$,而且轮廓线上其他都是黑的,我们可以放黑色。
所以这又是个特判。
4.对于3我们考虑的是上下断开,能否出现左右断开?
当然可能。
但是只能在最后一行出现。
所以统计答案时要填回去看一眼。
真 恶心。
深思熟虑后糊上去的代码:
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
#define N 15
#define ll long long
int T,n,m,k,a[N][N];
char ch[N][N];
ll bas[N],ans;
struct Map
{
int hed[],cnt[];
struct EG
{
int nxt;
ll to,w;
}e[2][];
void ae(int f,ll t,ll w)
{
e[++cnt[k]][k].to = t;
e[cnt[k]][k].nxt = hed[f];
e[cnt[k]][k].w = w;
hed[f] = cnt[k];
}
void push(ll u,ll w)
{
for(int j=hed[u%];j;j=e[j][k].nxt)
if(e[j][k].to==u)
{
e[j][k].w += w;
return ;
}
ae(u%,u,w);
}
void clear()
{
cnt[k] = ;
memset(hed,,sizeof(hed));
}
}mp;
int col[N],grp[N],tmp[N],las[N];
ll zip()
{
ll ret = ;
for(int i=;i<=m+;i++)ret=*(ret+grp[i]);
return ret+col[];
}
void upz(ll u)
{
memset(tmp,-,sizeof(tmp));
tmp[]=u%;u/=;
for(int i=m+;i>=;i--,u/=)grp[i]=u%;
for(int i=;i<=m+;i++)
if(tmp[grp[i]]==-)tmp[grp[i]]=tmp[grp[i-]]^;
for(int i=;i<=m+;i++)
col[i]=tmp[grp[i]];
}
void shake()//get the express
{
memset(tmp,,sizeof(tmp));
for(int cnt=,i=;i<=m+;i++)
if(!tmp[grp[i]])tmp[grp[i]]=++cnt;
for(int i=;i<=m+;i++)grp[i]=tmp[grp[i]];
}
bool find_friend(int now,int beg,int ens)
{
int cnt = ;
for(int i=beg;i<=ens;i++)
if(grp[i]==now)cnt++;
return cnt>;
}
bool ck1()
{
for(int i=;i<=m;i++)
if(col[i]+a[][i]==)return ;
return ;
}
bool ck2()
{
int cnt = ;
for(int i=;i<=m;i++)
cnt+=(col[i]!=col[i-]);
return cnt<=;
}
int ck3(int c)
{
if(col[m-]==col[m]&&col[m]==col[m+]&&col[m+]==c)return ;
int c0 = col[m],ret=;
for(int i=;i<=m+;i++)las[i]=grp[i];
col[m] = c;grp[m] = m+;
if(col[m-]==c)
{
int kg = grp[m-];
for(int i=;i<=m+;i++)if(grp[i]==kg)grp[i]=m+;
}
if(col[m+]==c)
{
int kg = grp[m+];
for(int i=;i<=m+;i++)if(grp[i]==kg)grp[i]=m+;
}
shake();
for(int i=;i<=m+;i++)if(grp[i]>)ret = ;
for(int i=;i<=m+;i++)grp[i] = las[i];
if(col[m-]==c)
{
int kg = grp[m-];
for(int i=;i<=m+;i++)if(grp[i]==kg)grp[i]=m+;
}
if(col[m+]==c)
{
int kg = grp[m+];
for(int i=;i<=m+;i++)if(grp[i]==kg)grp[i]=m+;
}
shake();
for(int i=;i<=m+;i++)if(grp[i]>)ret = ;
for(int i=;i<=m+;i++)grp[i]=las[i];
col[m] = c0;
return ret;
}
void PushF()
{
for(int i=;i<(<<m);i++)
{
for(int j=;j<=m;j++)col[j]=(i>>(j-))&;
if(!ck1())continue;
if(!ck2())continue;
grp[]=;
for(int j=;j<=m+;j++)if(col[j]==col[j-])grp[j]=grp[j-];else grp[j]=grp[j-]+;
mp.push(zip(),);
}
}
bool check_b(int i,int j)
{
if(a[i][j]==)return ;
if(col[j-]==&&col[j]==&&col[j+]==)return ;
if((i!=n||j!=m)&&(i!=n||j!=m-))
if(col[j+]==&&!find_friend(grp[j+],j+,m+)&&!find_friend(grp[j+],,j-))
return ;
return ;
}
bool check_w(int i,int j)
{
if(a[i][j]==)return ;
if(col[j-]==&&col[j]==&&col[j+]==)return ;
if((i!=n||j!=m)&&(i!=n||j!=m-))
if(col[j+]==&&!find_friend(grp[j+],j+,m+)&&!find_friend(grp[j+],,j-))
return ;
return ;
}
int main()
{
// freopen("tt.in","r",stdin);
scanf("%d",&T);
bas[]=;
for(int i=;i<=;i++)bas[i] = *bas[i-];
while(T--)
{
scanf("%d%d",&n,&m);
for(int i=;i<=n;i++)
{
scanf("%s",ch[i]+);
for(int j=;j<=m;j++)
{
if(ch[i][j]=='o')a[i][j]=;
else if(ch[i][j]=='#')a[i][j]=;
else a[i][j]=;
}
}
ans=,k=,mp.clear();
PushF();
for(int i=;i<=n;i++)
{
k^=;mp.clear();
for(int j=;j<=mp.cnt[!k];j++)
{
ll now = mp.e[j][!k].to,val = mp.e[j][!k].w;
upz(now);
for(int o=m+;o>=;o--)grp[o]=grp[o-],col[o]=col[o-];
for(int q=;q<=m+;q++)las[q]=grp[q];
if(a[i][]!=)//black
{
if(col[]==)
{
col[]=,grp[]=grp[];
shake();
mp.push(zip(),val);
}else
{
if(find_friend(grp[],,m+))
{
col[]=,grp[]=m+;
shake();
mp.push(zip(),val);
}else if(i==n&&m==)
{
col[]=,grp[]=m+;
shake();
mp.push(zip(),val);
}
}
}
for(int q=;q<=m+;q++)grp[q]=las[q];
if(a[i][]!=)//white
{
if(col[]==)
{
col[]=,grp[]=grp[];
shake();
mp.push(zip(),val);
}else
{
if(find_friend(grp[],,m+))
{
col[]=,grp[]=m+;
shake();
mp.push(zip(),val);
}else if(i==n&&m==)
{
col[]=,grp[]=m+;
shake();
mp.push(zip(),val);
}
}
}
}
for(int j=;j<=m;j++)
{
k^=,mp.clear();
for(int o=;o<=mp.cnt[!k];o++)
{
ll now = mp.e[o][!k].to,val = mp.e[o][!k].w;
upz(now);int c0 = col[j];
if(i==n&&j==m)
{
if(n==&&m==)
{
if(col[]==col[])
{
if((a[n][m]==||a[n][m]!=col[])&&col[]==col[])
ans+=val*ck3(col[]^);
else if((a[n][m]==||a[n][m]==col[])&&col[]!=col[])
ans+=val*ck3(col[]);
}else
{
if(a[n][m]==)ans+=val*(ck3()+ck3());
else ans+=val*ck3(a[n][m]);
}
}else
{
if(col[m-]==col[m+])
{
if(a[n][m]==||a[n][m]==col[m-])
ans+=val*ck3(col[m-]);
}else
{
if(a[n][m]==)ans+=val*(ck3()+ck3());
else ans+=val*ck3(a[n][m]);
}
}
continue;
}
if(check_b(i,j))//black
{
col[j]=;grp[j]=m+;
for(int q=;q<=m+;q++)las[q]=grp[q];
if(col[j-]==)
{
int kg = grp[j-];
for(int q=;q<=m+;q++)if(grp[q]==kg)grp[q]=m+;
}
if(col[j+]==)
{
int kg = grp[j+];
for(int q=;q<=m+;q++)if(grp[q]==kg)grp[q]=m+;
}
shake();
if(i==n&&j==m)ans+=val;
mp.push(zip(),val);
for(int q=;q<=m+;q++)grp[q]=las[q];
}
col[j] = c0;
if(check_w(i,j))//white
{
col[j]=;grp[j]=m+;
if(col[j-]==)
{
int kg = grp[j-];
for(int q=;q<=m+;q++)if(grp[q]==kg)grp[q]=m+;
}
if(col[j+]==)
{
int kg = grp[j+];
for(int q=;q<=m+;q++)if(grp[q]==kg)grp[q]=m+;
}
shake();
if(i==n&&j==m)ans+=val;
mp.push(zip(),val);
}
}
}
}
printf("%lld\n",ans);
}
return ;
}
bzoj3336 Uva10572 Black and White的更多相关文章
- BZOJ3336: Uva10572 Black and White(插头Dp)
解题思路: 分类讨论即可. 代码(懒得删Debug了): #include<map> #include<cstdio> #include<vector> #incl ...
- bzoj AC倒序
Search GO 说明:输入题号直接进入相应题目,如需搜索含数字的题目,请在关键词前加单引号 Problem ID Title Source AC Submit Y 1000 A+B Problem ...
- imshow() displays a white image for a grey image
Matlab expects images of type double to be in the 0..1 range and images that are uint8 in the 0..255 ...
- ural 2063. Black and White
2063. Black and White Time limit: 1.0 secondMemory limit: 64 MB Let’s play a game. You are given a r ...
- 彩色照片转换为黑白照片(Color image converted to black and white picture)
This blog will be talking about the color image converted to black and white picture. The project st ...
- HDU 5113 Black And White 回溯+剪枝
题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=5113 Black And White Time Limit: 2000/2000 MS (Java/ ...
- SCU3185 Black and white(二分图最大点权独立集)
题目大概说有几个黑色.白色矩阵,问能选出黑白不相交的矩形面积和的最大值. 建二分图,黑色矩阵为X部的点,白色为Y部,XY的点权都为其矩阵面积,如果有个黑白矩阵相交则它们之间有一条边,那样问题就是要从这 ...
- White Rectangles[HDU1510]
White Rectangles Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) ...
- nVIDIA SDK White Paper ----Vertex Texture Fetch Water
http://blog.csdn.net/soilwork/article/details/713842 nVIDIA SDK White Paper ----Vertex Texture Fetch ...
随机推荐
- (水题)洛谷 - P1149 - 火柴棒等式
https://www.luogu.org/problemnew/show/P1149 一开始还分类重复了.在非0的dfs中居然赋值了0,脑残得一笔. 其实就按 $lead0$ 分类就好了, $lea ...
- python 容器 生成器 迭代器 总结
一.容器 容器是一种把多个元素组织在一起的数据结构,容器中的元素可以逐个地迭代获取,可以用in, not in关键字判断元素是否包含在容器中.通常这类数据结构把所有的元素存储在内存中. >> ...
- IT兄弟连 Java Web教程 Tomcat
本文采用的Tomcat服务器版本是Tomcat8.5版本,Tomcat8.5支持Servlet3.1.JSP2.3以及EL3.0规范.并且Tomcat8.5版本对JDK8的支持比Tomcat8更加全面 ...
- Ascall码的故事
没事发个ascall码表,二进制值得研究呦 sub al,30h; and al,00001111b ;字符ascall转数字or al,00110000b; sub al,32; and al,11 ...
- IO流案例:1.复制多级文件夹 2.删除多级文件夹
package copy; /* 需求:复制多级文件夹 复制d:\\itcast(包含文件和子文件夹)到模块目录下 分析: d:\\itcast a.txt b.txt javaweb a.xml b ...
- 2015 ACM-ICPC国际大学生程序设计竞赛北京赛区网络赛 1002 Mission Impossible 6
题目链接: #1228 : Mission Impossible 6 解题思路: 认真读题,细心模拟,注意细节,就没有什么咯!写这个题解就是想记录一下rope的用法,以后忘记方便复习. rope(块状 ...
- Codeforces 1107E(区间dp)
用solve(l, r, prefix)代表区间l开始r结束.带了prefix个前缀str[l](即l前面的串化简完压缩成prefix-1个str[l],加上str[l]共有prefix个)的最大值. ...
- UVa 12186 Another Crisis 工人的请愿书
c表示某上司上报的最少请愿下属,k表示总下属c=0.01T*k=kT/100(0.01T*k是整数)c=[0.01T*k]+1=[kT/100]+1(0.01T*k不是整数) kT=100 c=1 k ...
- [已读]图解CSS3核心技术与案例实战
买的时候犹豫了好久,也征询了下几个前端朋友.我一直蛮怕买华章的书,好在这本内容很不错,买得值了. 大漠的css功底很深厚,这本书也很厚= =,读完之后对css圆角以及background-origin ...
- qconbeijing2018
https://2018.qconbeijing.com/schedule 会议 · 第一天 (2018/04/20 周五) 时间 日程 上午 主题演讲 大数据下的软件质量建设实践 黄闻欣 出品 人工 ...