3 条题解
-
2
#include<bits/stdc++.h> #define MAXN 25 #define p 100007 #define int long long using namespace std; int n,m,K,now,pre; char c[MAXN][MAXN]; int head[p+3],nxt[1<<24]; int f[2][1<<24],fst[2][3][1<<24]; int cnt[2]; void insert(int state1,int state2,int state3,int val) { int ha=((((1ll*state1<<16)|state2)<<4)|state3)%p+1;//哈希 for(int i=head[ha];i;i=nxt[i]) if(fst[now][0][i]==state1&&fst[now][1][i]==state2&&fst[now][2][i]==state3) { f[now][i]=max(f[now][i],val); return; } f[now][++cnt[now]]=val; fst[now][0][cnt[now]]=state1; fst[now][1][cnt[now]]=state2; fst[now][2][cnt[now]]=state3;//三个状态 nxt[cnt[now]]=head[ha]; head[ha]=cnt[now]; }//hash表 int left(int state,int pos,int val) {//向左寻找左括号 int tot=1; while(true) { int pl=(state>>(pos<<1))&3; if(pl==2)tot++;if(pl==1) tot--; if(!tot)return state^(pl<<(pos<<1))^(val<<(pos<<1)); pos--; } } int right(int state,int pos,int val) {//向右寻找右括号 int tot=1; while(true) { int pl=(state>>(pos<<1))&3; if(pl==1)tot++;if(pl==2) tot--; if(!tot)return state^(pl<<(pos<<1))^(val<<(pos<<1)); pos++; } } char tmp[MAXN][MAXN]; signed main() { scanf("%lld%lld%lld",&n,&m,&K); for(int i=0;i<n;i++)scanf("%s",c[i]); if(n<m) {//n<m的时候把地图转90度 memcpy(tmp,c,sizeof(c)); for(int i=0;i<n;i++) for(int j=0;j<m;j++) c[j][i]=tmp[i][j]; swap(n,m); } cnt[0]=1; for(int i=0;i<n;i++) { for(int j=1;j<=cnt[now];j++) fst[now][0][j]<<=2; for(int j=1;j<=cnt[now];j++) fst[now][1][j]=(fst[now][1][j]^(((fst[now][1][j]>>(m+1<<1))&3)<<(m+1<<1)))<<2;//更新上一行的状态 for(int j=0;j<m;j++) { pre=now;now^=1;cnt[now]=0; memset(head,0,sizeof(head));//注意初始化 for(int k=1;k<=cnt[pre];k++) { int sta=fst[pre][0][k],stb=fst[pre][1][k],stc=fst[pre][2][k]; int val=f[pre][k]; if(sta>=(1<<(m+1<<1)))continue; int pl1=(sta>>(j<<1))&3;//right int pl2=(sta>>(j+1<<1))&3;//down int r=(stb>>(j<<1))&3;//右状态 int ur=(stb>>(j+1<<1))&3;//右上状态 int u=(stb>>(j+2<<1))&3;//上状态 int ul=(stb>>(j+3<<1))&3;//左上状态 int now=(sta^(pl1<<(j<<1))^(pl2<<(j+1<<1))); if((!pl1&&r==1)||(!pl2&&u==1))//1 { if(pl1||pl2)continue; insert(now,stb^(ur<<(j+1<<1)),stc,val);//放障碍 if(stc<K&&c[i][j]=='.') insert(now,stb^(ur<<(j+1<<1))^(3<<(j+1<<1)),stc+1,val+(r==1)+(ur==1)+(u==1)+(ul==1));//放炮台 } else if(c[i][j]=='#'){if(!pl1&&!pl2)insert(now,stb^(ur<<(j+1<<1)),stc,val);}//2 else if(c[i][j]=='.')//3 { if(!pl1&&!pl2)//1) { if(stc<K) insert(now,stb^(ur<<(j+1<<1))^(3<<(j+1<<1)),stc+1, val+(r==1)+(ur==1)+(u==1)+(ul==1));//放炮台 insert(now^(1<<(j<<1))^(2<<(j+1<<1)),stb^(ur<<(j+1<<1))^(1<<(j+1<<1)),stc, val+(r==3)+(ur==3)+(u==3)+(ul==3));//走 insert(now,stb^(ur<<(j+1<<1)),stc,val);//不走 } else if(!pl1&&pl2)//2) { insert(now^(pl2<<(j<<1)),stb^(ur<<(j+1<<1))^(1<<(j+1<<1)),stc, val+(r==3)+(ur==3)+(u==3)+(ul==3)); insert(now^(pl2<<(j+1<<1)),stb^(ur<<(j+1<<1))^(1<<(j+1<<1)),stc, val+(r==3)+(ur==3)+(u==3)+(ul==3)); } else if(pl1&&!pl2)//2) { insert(now^(pl1<<(j<<1)),stb^(ur<<(j+1<<1))^(1<<(j+1<<1)),stc, val+(r==3)+(ur==3)+(u==3)+(ul==3)); insert(now^(pl1<<(j+1<<1)),stb^(ur<<(j+1<<1))^(1<<(j+1<<1)),stc, val+(r==3)+(ur==3)+(u==3)+(ul==3)); } else if(pl1==1&&pl2==1)//3) insert(right(now,j,1),stb^(ur<<(j+1<<1))^(1<<(j+1<<1)),stc, val+(r==3)+(ur==3)+(u==3)+(ul==3)); else if(pl1==2&&pl2==2)//4) insert(left(now,j,2),stb^(ur<<(j+1<<1))^(1<<(j+1<<1)),stc, val+(r==3)+(ur==3)+(u==3)+(ul==3)); else if(pl1==2&&pl2==1)//6) insert(now,stb^(ur<<(j+1<<1))^(1<<(j+1<<1)),stc, val+(r==3)+(ur==3)+(u==3)+(ul==3)); else if(pl1==1&&pl2==3)//7) insert(right(now,j,3),stb^(ur<<(j+1<<1))^(1<<(j+1<<1)),stc, val+(r==3)+(ur==3)+(u==3)+(ul==3)); else if(pl1==2&&pl2==3)//8) insert(left(now,j,3),stb^(ur<<(j+1<<1))^(1<<(j+1<<1)),stc, val+(r==3)+(ur==3)+(u==3)+(ul==3)); else if(pl1==3&&pl2==1)//7) insert(right(now,j,3),stb^(ur<<(j+1<<1))^(1<<(j+1<<1)),stc, val+(r==3)+(ur==3)+(u==3)+(ul==3)); else if(pl1==3&&pl2==2)//8) insert(left(now,j,3),stb^(ur<<(j+1<<1))^(1<<(j+1<<1)),stc, val+(r==3)+(ur==3)+(u==3)+(ul==3)); else if(pl1==3&&pl2==3)//9) insert(now,stb^(ur<<(j+1<<1))^(1<<(j+1<<1)),stc, val+(r==3)+(ur==3)+(u==3)+(ul==3)); } else if(c[i][j]=='S'||c[i][j]=='T')//4 { if(c[i][j]=='S'&&!pl1&&!pl2)//1) { insert(now^(3<<(j<<1)),stb^(ur<<(j+1<<1))^(1<<(j+1<<1)),stc, val+(r==3)+(ur==3)+(u==3)+(ul==3)); insert(now^(3<<(j+1<<1)),stb^(ur<<(j+1<<1))^(1<<(j+1<<1)),stc, val+(r==3)+(ur==3)+(u==3)+(ul==3)); } else if(c[i][j]=='T'&&!pl1&&!pl2)//1) { insert(now^(3<<(j<<1)),stb^(ur<<(j+1<<1))^(1<<(j+1<<1)),stc, val+(r==3)+(ur==3)+(u==3)+(ul==3)); insert(now^(3<<(j+1<<1)),stb^(ur<<(j+1<<1))^(1<<(j+1<<1)),stc, val+(r==3)+(ur==3)+(u==3)+(ul==3)); } else if(!pl1&&pl2==1)//2) insert(right(now,j,3),stb^(ur<<(j+1<<1))^(1<<(j+1<<1)),stc, val+(r==3)+(ur==3)+(u==3)+(ul==3)); else if(!pl1&&pl2==2)//3) insert(left(now,j,3),stb^(ur<<(j+1<<1))^(1<<(j+1<<1)),stc, val+(r==3)+(ur==3)+(u==3)+(ul==3)); else if(pl1==1&&!pl2)//2) insert(right(now,j,3),stb^(ur<<(j+1<<1))^(1<<(j+1<<1)),stc, val+(r==3)+(ur==3)+(u==3)+(ul==3)); else if(pl1==2&&!pl2)//3) insert(left(now,j,3),stb^(ur<<(j+1<<1))^(1<<(j+1<<1)),stc, val+(r==3)+(ur==3)+(u==3)+(ul==3)); else if(pl1==3&&!pl2)//4) insert(now,stb^(ur<<(j+1<<1))^(1<<(j+1<<1)),stc, val+(r==3)+(ur==3)+(u==3)+(ul==3)); else if(!pl1&&pl2==3)//4) insert(now,stb^(ur<<(j+1<<1))^(1<<(j+1<<1)),stc, val+(r==3)+(ur==3)+(u==3)+(ul==3)); } } } } int ans=0; for(int i=1;i<=cnt[now];i++)//统计答案 if(!fst[now][0][i]) ans=max(ans,f[now][i]); printf("%lld",ans); return 0; }
信息
- ID
- 2626
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- 9
- 标签
- 递交数
- 11
- 已通过
- 3
- 上传者