3 条题解

  • 2
    @ 2026-6-27 20:46:23
    //水题一道
    #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
    上传者