记录编号 |
596823 |
评测结果 |
AAAAAAAAAA |
题目名称 |
[UVa 10572] 黑和白 |
最终得分 |
100 |
用户昵称 |
flyfree |
是否通过 |
通过 |
代码语言 |
C++ |
运行时间 |
1.260 s |
提交时间 |
2024-11-08 16:13:52 |
内存使用 |
164.57 MiB |
显示代码纯文本
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define MAXN 100010
#define mod 29987
#define lst now-1
inline ll read(){
ll x=0,f=1;
char c=getchar();
while(c<'0'||c>'9'){
if(c=='-')f=-1;
c=getchar();
}
while(c>='0'&&c<='9'){
x=x*10+c-'0';
c=getchar();
}
return x*f;
}
ll dp[70][MAXN],que[70][MAXN],frm[70][MAXN],cnt[70];
ll s[10][10],pre[15],ans_c[10][10],_col[20];
ll hd[30010],nxt[MAXN];
ll T,n,m,now,wx,wy,bx,by,k,sum_ans;
char c;
void insert(ll sta,ll val,ll fr){
ll u=sta%mod;
for(int i=hd[u];i;i=nxt[i]){
if(que[now][i]==sta){
dp[now][i]+=val;
return;
}
}
nxt[++cnt[now]]=hd[u];
hd[u]=cnt[now];
dp[now][cnt[now]]=val;
que[now][cnt[now]]=sta;
frm[now][cnt[now]]=fr;
}
ll work(ll sta){
ll idxw=2,idxb=1,y=0;
memset(_col,0,sizeof(_col));
for(int i=1;i<=m;i++){
ll col=(sta>>(i-1)*4)%16;
if(!col)continue;
if(!_col[col]){
if(col%2==1)_col[col]=idxb,idxb+=2;
else _col[col]=idxw,idxw+=2;
}
y+=_col[col]*pre[i];
}
return y;
}
void write(ll sta){
if((sta>>m*4)%16==1)cout<<"Black ";
else if((sta>>m*4)%16==2)cout<<"White ";
else cout<<"Empty ";
// cout<<(sta>>m*4)%16<<" ";
for(int i=1;i<=m;i++){
cout<<(sta>>(i-1)*4)%16<<" ";
}
// cout<<endl;
}
ll pd(ll x,ll y,ll sta,ll col){
if((x<n&&y<m)||x<n-1)return 0;
if((sta>>m*4)%2==col&&(sta>>(y-1)*4)%2==col&&(y>1&&(sta>>(y-2)*4)%2==col))return 0;
ll re_ans=0;
for(int i=1;i<=m;i++){
ll col_now=(sta>>(i-1)*4)%16;
if(col_now%2!=col)re_ans=max(re_ans,col_now);
}
if(re_ans>2)return 0;
if(x==n){
for(int i=y+1;i<=m;i++){
ll col_now=(sta>>((i-1)*4))%2,col_lst=(sta>>((i-2)*4))%2;
if(col_now==col_lst&&col_now==col)return 0;
}
return 1;
}else{
for(int i=2;i<=m;i++){
ll col_now=i==m?col:(sta>>((i-1)*4))%2,col_lst=(sta>>((i-2)*4))%2;
if(col_now==col_lst&&col_now==col)return 0;
}
return 1;
}
}
ll re_max(ll sta){
ll re_ans=0;
for(int i=1;i<=m;i++){
re_ans=max(re_ans,(sta>>(i-1)*4)%16);
}
return re_ans;
}
void clear(){
memset(dp,0,sizeof(dp));
memset(que,0,sizeof(que));
memset(cnt,0,sizeof(cnt));
memset(frm,0,sizeof(frm));
memset(ans_c,0,sizeof(ans_c));
memset(hd,0,sizeof(hd));
memset(nxt,0,sizeof(nxt));
k=0;
wx=0,wy=0,bx=0,by=0,now=0,sum_ans=0;
}
void clear_ans(ll x,ll y,ll i,ll col){
ll qwe=lst;
ll h=i;
for(int u=y-1;u;u--){
if((que[qwe][h]>>(u-1)*4)%2)ans_c[x][u]=1;
else ans_c[x][u]=2;
h=frm[qwe][h];
qwe--;
}
for(int j=x-1;j;j--){
for(int u=m;u;u--){
if((que[qwe][h]>>(u-1)*4)%2)ans_c[j][u]=1;
else ans_c[j][u]=2;
h=frm[qwe][h];
qwe--;
}
}
k=1;
if(x!=n||y!=m){
for(int j=y;j<=m;j++)ans_c[x][j]=col;
for(int j=1;j<=m;j++)ans_c[n][j]=col;
}
}
int main(){
freopen("blackandwhite.in","r",stdin);
freopen("blackandwhite.out","w",stdout);
// cin>>T;
T=1;
pre[1]=1;
for(int i=2;i<=10;i++)pre[i]=pre[i-1]<<4;
while(T--){
clear();
cin>>n>>m;
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
cin>>c;
if(c=='.')s[i][j]=0;
else if(c=='#')s[i][j]=1,bx=i,by=j;
else s[i][j]=2,wx=i,wy=j;
}
}
que[0][++cnt[now]]=0;
dp[0][1]=1;
for(int i=1;i<=n;i++){
for(int j=1;j<=cnt[now];j++)que[now][j]%=pre[m+1];
for(int j=1;j<=m;j++){
now++;
memset(hd,0,sizeof(hd));
memset(nxt,0,sizeof(nxt));
// cout<<"\n-------------\n";
// cout<<i<<" "<<j<<endl;
for(int u=1;u<=cnt[lst];u++){
ll g=0,p_up=(que[lst][u]>>(j-1)*4)%16,p_rht=j>1?(que[lst][u]>>(j-2)*4)%16:0,_p=(que[lst][u]>>m*4)%16;
// write(que[lst][u]);
for(int sz=1;sz<=m;sz++){
if((que[lst][u]>>(sz-1)*4)%16==p_up&&sz!=j)g=1;
}
// cout<<"val: "<<dp[lst][u]<<endl;
if(s[i][j]!=2&&((p_up==0||p_up%2==0)||(p_rht==0||p_rht%2==0)||(_p%2==0||_p==0))){//染成黑格
if(!g&&p_up%2==0&&p_up!=0){
// if((i>wx||(i>=wx&&j>wy))&&!k)
if((i>wx||(i>=wx&&j>wy))&&pd(i,j,que[lst][u],1)){
sum_ans+=dp[lst][u];
if(!k)clear_ans(i,j,u,1);
// cout<<"UNO! Black\n";
}
}else{
ll y=que[lst][u];
for(int sz=1;sz<=m;sz++){
ll col=(que[lst][u]>>(sz-1)*4)%16;
if(((col%2==1&&col==p_up)||(col%2==1&&col==p_rht))&&col!=0&&sz!=j){
y=y-col*pre[sz]+pre[sz]*15;
}
}
y=y-p_up*pre[j]+15*pre[j];
// cout<<y<<endl;
y=work(y);
y=y%pre[m+1]+(p_up%2==0?(p_up==0?0:2):1)*pre[m+1];
// cout<<"To: ";
// write(y);
// cout<<endl;
insert(y,dp[lst][u],u);
}
}
if(s[i][j]!=1&&((p_up==0||p_up%2==1)||(p_rht==0||p_rht%2==1)||(_p==0||_p%2==1))){//染成白格
if(!g&&p_up%2==1&&p_up!=0){
if((i>bx||(i>=bx&&j>by))&&pd(i,j,que[lst][u],0)){
sum_ans+=dp[lst][u];
if(!k)clear_ans(i,j,u,2);
// cout<<"UNO! White\n";
}
}else{
ll y=que[lst][u];
for(int sz=1;sz<=m;sz++){
ll col=(que[lst][u]>>(sz-1)*4)%16;
if(((col%2==0&&col==p_up)||(col%2==0&&col==p_rht))&&col!=0&&sz!=j){
y=y-col*pre[sz]+pre[sz]*14;
}
}
y=y-p_up*pre[j]+14*pre[j];
// cout<<y<<" ";
y=work(y);
// cout<<"To: ";
y=y%pre[m+1]+(p_up%2==0?(p_up==0?0:2):1)*pre[m+1];
// write(y);
// cout<<endl;
// cout<<y<<endl;
insert(y,dp[lst][u],u);
}
}
}
}
}
now++;
for(int i=1;i<=cnt[lst];i++){
// cout<<"\n-------\n";
// write(que[lst][i]);
// cout<<re_max(que[lst][i])<<endl;
if(re_max(que[lst][i])>2)continue;
sum_ans+=dp[lst][i];
if(!k){
clear_ans(n,m,i,0);
}
}
cout<<sum_ans<<endl;
// if(sum_ans==0)continue;
// for(int i=1;i<=n;i++){
// for(int j=1;j<=m;j++){
// if(ans_c[i][j]==1)cout<<'#';
// else cout<<'o';
// }
// cout<<endl;
// }
}
return 0;
}