BZOJ3723 : PA2014Final Gra w podwajanie
2016-03-17 19:35
148 查看
暴力搜索出所有可行的形状,可以发现本质不同的形状数只有6000个左右。
对于每个形状,它的大小不超过$8\times 8$,故可以按照右下角为原点重建坐标系,用一个unsigned long long来存储。
然后对于每个中心,先进行第一步扩展,若能成功扩展,则扫描所有形状,看看是否匹配即可。
时间复杂度$O(6000nm)$。
对于每个形状,它的大小不超过$8\times 8$,故可以按照右下角为原点重建坐标系,用一个unsigned long long来存储。
然后对于每个中心,先进行第一步扩展,若能成功扩展,则扫描所有形状,看看是否匹配即可。
时间复杂度$O(6000nm)$。
#include<cstdio> #include<algorithm> using namespace std; typedef unsigned long long ll; const int N=210,M=30000; int dx[4]={-1,1,0,0},dy[4]={0,0,-1,1};ll state[8][8]; int n,m,i,j,k,ans[6]={0,1,2,4,8,16};char a ,f ; struct Shape{ int st ,en ,ed,v [2],cnt[5][5];ll q[5][5][M]; inline void add(int x,int y){st[++ed]=x;en[ed]=y;} void dfs(int x){ if(x>ed){ int a=0,b=0; for(int i=1;i<=x;i++)a=max(a,v[i][0]),b=max(b,v[i][1]); ll t=0; for(int i=1;i<=x;i++)t|=state[a-v[i][0]][b-v[i][1]]; q[a][b][++cnt[a][b]]=t; return; } for(int i=0;i<4;i++){ int X=v[st[x]][0]+dx[i],Y=v[st[x]][1]+dy[i],flag=1; for(int j=1;j<=x;j++)if(v[j][0]==X&&v[j][1]==Y){flag=0;break;} if(flag)v[en[x]][0]=X,v[en[x]][1]=Y,dfs(x+1); } } void init(int k){ if(k==2){ add(1,2); } if(k==3){ add(1,2); add(1,3); add(2,4); } if(k==4){ add(1,2); add(1,3); add(1,4); add(2,5); add(2,6); add(3,7); add(5,8); } if(k==5){ add(1,2); add(1,3); add(1,4); add(1,5); add(2,6); add(2,7); add(2,8); add(3,9); add(3,10); add(4,11); add(6,12); add(6,13); add(7,14); add(9,15); add(12,16); } dfs(1); for(int i=0;i<5;i++)for(int j=0;j<5;j++)if(cnt[i][j]){ sort(q[i][j]+1,q[i][j]+cnt[i][j]+1); int k=0; for(int x=1;x<=cnt[i][j];x++)if(q[i][j][x]!=q[i][j][x-1])q[i][j][++k]=q[i][j][x]; cnt[i][j]=k; } } }G[6]; inline bool check(int x,int y,int z){ if(f[x][y]<z-1)return 0; if(f[x][y]>=z)return 1; if(z<5)return 1; if(check(x-1,y,1)&&check(x+1,y,2)&&check(x,y-1,3)&&check(x,y+1,4))return 1; if(check(x-1,y,1)&&check(x+1,y,2)&&check(x,y-1,4)&&check(x,y+1,3))return 1; if(check(x-1,y,1)&&check(x+1,y,3)&&check(x,y-1,2)&&check(x,y+1,4))return 1; if(check(x-1,y,1)&&check(x+1,y,3)&&check(x,y-1,4)&&check(x,y+1,2))return 1; if(check(x-1,y,1)&&check(x+1,y,4)&&check(x,y-1,2)&&check(x,y+1,3))return 1; if(check(x-1,y,1)&&check(x+1,y,4)&&check(x,y-1,3)&&check(x,y+1,2))return 1; if(check(x-1,y,2)&&check(x+1,y,1)&&check(x,y-1,3)&&check(x,y+1,4))return 1; if(check(x-1,y,2)&&check(x+1,y,1)&&check(x,y-1,4)&&check(x,y+1,3))return 1; if(check(x-1,y,2)&&check(x+1,y,3)&&check(x,y-1,1)&&check(x,y+1,4))return 1; if(check(x-1,y,2)&&check(x+1,y,3)&&check(x,y-1,4)&&check(x,y+1,1))return 1; if(check(x-1,y,2)&&check(x+1,y,4)&&check(x,y-1,1)&&check(x,y+1,3))return 1; if(check(x-1,y,2)&&check(x+1,y,4)&&check(x,y-1,3)&&check(x,y+1,1))return 1; if(check(x-1,y,3)&&check(x+1,y,1)&&check(x,y-1,2)&&check(x,y+1,4))return 1; if(check(x-1,y,3)&&check(x+1,y,1)&&check(x,y-1,4)&&check(x,y+1,2))return 1; if(check(x-1,y,3)&&check(x+1,y,2)&&check(x,y-1,1)&&check(x,y+1,4))return 1; if(check(x-1,y,3)&&check(x+1,y,2)&&check(x,y-1,4)&&check(x,y+1,1))return 1; if(check(x-1,y,3)&&check(x+1,y,4)&&check(x,y-1,1)&&check(x,y+1,2))return 1; if(check(x-1,y,3)&&check(x+1,y,4)&&check(x,y-1,2)&&check(x,y+1,1))return 1; if(check(x-1,y,4)&&check(x+1,y,1)&&check(x,y-1,2)&&check(x,y+1,3))return 1; if(check(x-1,y,4)&&check(x+1,y,1)&&check(x,y-1,3)&&check(x,y+1,2))return 1; if(check(x-1,y,4)&&check(x+1,y,2)&&check(x,y-1,1)&&check(x,y+1,3))return 1; if(check(x-1,y,4)&&check(x+1,y,2)&&check(x,y-1,3)&&check(x,y+1,1))return 1; if(check(x-1,y,4)&&check(x+1,y,3)&&check(x,y-1,1)&&check(x,y+1,2))return 1; if(check(x-1,y,4)&&check(x+1,y,3)&&check(x,y-1,2)&&check(x,y+1,1))return 1; return 0; } inline bool ok(int x,int y){ if(x<1||x>n||y<1||y>m)return 0; return a[x][y]; } inline bool judge(int x,int y,int z){ int i,j,k,l; for(i=0;i<5;i++)for(j=0;j<5;j++){ ll t=0; for(k=0;k<8;k++)for(l=0;l<8;l++)if(ok(x+i-k,y+j-l))t|=state[k][l]; for(k=G[z].cnt[i][j];k;k--)if((G[z].q[i][j][k]&t)==G[z].q[i][j][k])return 1; } return 0; } int main(){ for(i=0;i<8;i++)for(j=0;j<8;j++)state[i][j]=1ULL<<(i*8+j); for(i=2;i<=5;i++)G[i].init(i); scanf("%d%d",&n,&m); for(i=1;i<=n;i++)for(scanf("%s",a[i]+1),j=1;j<=m;j++)a[i][j]-='0'; for(i=1;i<=n;i++)for(j=1;j<=m;j++)f[i][j]=a[i][j]; for(k=2;k<=5;k++)for(i=1;i<=n;i++)for(j=1;j<=m;j++)if(check(i,j,k))if(judge(i,j,k))f[i][j]++; for(i=1;i<=n;i++)for(j=1;j<=m;j++)printf("%d%c",ans[f[i][j]],j<m?' ':'\n'); return 0; }
相关文章推荐
- 经典排序算法(2) -插入排序 InsertSort
- struts2文件上传 下载
- PAT 乙级 真题 1002. 写出这个数
- 【HDU1863】畅通工程 (kruskal/并查集find)
- popToRootViewController
- Swift开发第七篇——字面量转换&下标
- Dex动态加载
- 操练Ubuntu14.10
- 学习笔记<一>
- C++标准库的异常类层次结构
- 排序——插入排序(C++)
- ADB server didn't ACK failed to start daemon 完美解决汇总
- ListView滑动位置精准记忆
- QT 格式化字符串功能
- Android 使用动态加载框架DL进行插件化开发
- Problem q
- C语言中的static 详细分析
- JavaScript实现图片轮播
- 初学android
- Hadoop2.2.0 HA初体验