E - Xenia and Dominoes







感谢lzxiang提供题解以及代码









#include<cstdio>
#include<cstring>
#include<iostream>
using namespace std;

/*
  设计状态:dp[i][j][k][l]表示在i列,状态为j,k,l时的方案数 
*/

const int MOD=1000000007;

struct dog
{
  int x1,y1,x2,y2;
}egg[5];

int n,sx=-1,sy=-1,cnt=0;

char s[50][10000+10];

long long dp[10000+10][2][2][2];

int dx[]={1,0,-1,0};
int dy[]={0,1,0,-1};

dog get(int x1,int y1,int x2,int y2)
{
  dog a;
  a.x1=x1;a.y1=y1;a.x2=x2;a.y2=y2;
  return a;
}

long long dfs()
{
  for(int i=0;i<n;i++)
  {
  	dp[i][1][1][1]=dp[i][1][1][0]=dp[i][1][0][1]=dp[i][0][1][1]=0;
  	dp[i][1][0][0]=dp[i][0][0][1]=dp[i][0][1][0]=dp[i][0][0][0]=0;
  }
	
  int ss1=(int)(s[1][0]!='.'),ss2=(int)(s[2][0]!='.'),ss3=(int)(s[3][0]!='.');
	
  dp[0][ss1][ss2][ss3]=1;
  
  if(s[1][0]=='.'&&s[2][0]=='.')
  {
  	dp[0][1][1][ss3]++;
  }
  //printf("%d\n",dp[0][(s[1][0]!='.')][1][1]);
  if(s[3][0]=='.'&&s[2][0]=='.')
  {
    dp[0][ss1][1][1]++; 
  }
  
  //printf("%d %d %d %d\n",dp[0][1][1][1],dp[0][1][1][0],dp[0][0][1][1],dp[0][0][0][0]);
  
  for(int i=1;i<n;i++)
  {
  	 ss1=(int)(s[1][i]!='.'),ss2=(int)(s[2][i]!='.'),ss3=(int)(s[3][i]!='.');
  	 //shuzhi
     if(s[1][i]=='.'&&s[2][i]=='.')
     {
     	if(dp[i-1][1][1][0]&&s[3][i]=='.')
     	{
     		dp[i][1][1][1]+=dp[i-1][1][1][0];
     	}
     	if(dp[i-1][1][1][1])
     	{
     		if(s[3][i]=='.')dp[i][1][1][0]+=dp[i-1][1][1][1];
     		else dp[i][1][1][1]+=dp[i-1][1][1][1];
     	}
     }
     if(s[3][i]=='.'&&s[2][i]=='.')
     {
     	if(dp[i-1][0][1][1]&&s[1][i]=='.')
     	{
     		dp[i][1][1][1]+=dp[i-1][0][1][1];
     	}
     	if(dp[i-1][1][1][1])
     	{
     		if(s[1][i]=='.')dp[i][0][1][1]+=dp[i-1][1][1][1];
     		else dp[i][1][1][1]+=dp[i-1][1][1][1];
     	}
     }
     //hengxiang
     if(s[1][i-1]=='.'&&s[1][i]=='.')
     {
     	if(dp[i-1][0][1][1])dp[i][1][ss2][ss3]+=dp[i-1][0][1][1];
        if(s[2][i-1]=='.'&&s[2][i]=='.')
        {
            if(dp[i-1][0][0][1])dp[i][1][1][ss3]+=dp[i-1][0][0][1];	
            if(s[3][i-1]=='.'&&s[3][i]=='.')
            {
            	if(dp[i-1][0][0][0])dp[i][1][1][1]+=dp[i-1][0][0][0];
            }
		}
        if(s[3][i-1]=='.'&&s[3][i]=='.')
        {
            if(dp[i-1][0][1][0])dp[i][1][ss2][1]+=dp[i-1][0][1][0];	
        }
	 }
	 if(s[2][i-1]=='.'&&s[2][i]=='.')
	 {
	 	if(dp[i-1][1][0][1])dp[i][ss1][1][ss3]+=dp[i-1][1][0][1];
	    if(s[3][i-1]=='.'&&s[3][i]=='.')
        {
            if(dp[i-1][1][0][0])dp[i][ss1][1][1]+=dp[i-1][1][0][0];	
        }
	 }
	 if(s[3][i-1]=='.'&&s[3][i]=='.')
	 {
	 	if(dp[i-1][1][1][0])dp[i][ss1][ss2][1]+=dp[i-1][1][1][0];
	 }
	 dp[i][ss1][ss2][ss3]=dp[i-1][1][1][1];
	 dp[i][1][1][1]%=MOD;dp[i][1][1][0]%=MOD;dp[i][1][0][1]%=MOD;dp[i][0][1][1]%=MOD;
	 dp[i][1][0][0]%=MOD;dp[i][0][0][1]%=MOD;dp[i][0][1][0]%=MOD;dp[i][0][0][0]%=MOD;
  }
  
  if(dp[n-1][1][1][1]<=0)return 0;
  return dp[n-1][1][1][1];
  
}

void work()
{
  for(int i=0;i<4;i++)//4个方位
  {
  	int x1=sx+dx[i],y1=sy+dy[i];
  	int x2=x1+dx[i],y2=y1+dy[i];
	if(x1>=0&&x2>=0&&x1<n&&x2<n&&y1>0&&y2>0&&y1<=3&&y2<=3&&s[y1][x1]=='.'&&s[y2][x2]=='.')
	{
		egg[++cnt]=get(y1,x1,y2,x2);
	}
  } 
  //printf("%d %d %d\n",sx,sy,cnt);
  //下方容斥原理 
  long long ans=0;
  
  if(cnt>=1)
  {
  	for(int i=1;i<=cnt;i++)
  	{
  	  s[egg[i].x1][egg[i].y1]='X';
  	  s[egg[i].x2][egg[i].y2]='X';
  	  ans=(ans+dfs())%MOD;
  	  s[egg[i].x1][egg[i].y1]='.';
  	  s[egg[i].x2][egg[i].y2]='.';
  	}
  }
  if(cnt>=2)
  {
  	for(int i=1;i<cnt;i++)
  	for(int j=i+1;j<=cnt;j++)
  	{
  	  s[egg[i].x1][egg[i].y1]='X';
  	  s[egg[i].x2][egg[i].y2]='X';
  	  s[egg[j].x1][egg[j].y1]='X';
  	  s[egg[j].x2][egg[j].y2]='X';
  	  ans-=dfs();
  	  while(ans<0)ans+=MOD;
  	  ans%=MOD;
  	  s[egg[i].x1][egg[i].y1]='.';
  	  s[egg[i].x2][egg[i].y2]='.';
  	  s[egg[j].x1][egg[j].y1]='.';
  	  s[egg[j].x2][egg[j].y2]='.';
  	}
  }
  if(cnt>=3)
  {
  	for(int i=1;i<=cnt;i++)
  	{
  	  s[egg[i].x1][egg[i].y1]='X';
  	  s[egg[i].x2][egg[i].y2]='X';
  	}
  	ans=(ans+dfs())%MOD;
  }
  
  cout<<ans<<endl;
  
}

int main()
{
  scanf("%d",&n);
  
  for(int i=1;i<=3;i++)
  {
  	scanf("%s",s[i]);
  }
  
  for(int i=1;i<=3;i++)
  {
  	for(int j=0;j<n;j++)
  	{
  	  if(s[i][j]=='O')
  	  {
  	  	sx=j;sy=i;break;
  	  }
  	}
  	if(sx!=-1)break;
  }
  
  //printf("%d %d %c",sx,sy,s[2][1]);
  
  work();
  
  return 0;
}


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
该资源内项目源码是个人的课程设计,代码都测试ok,都是运行成功后才上传资源,答辩评审平均分达到96分,放心下载使用! ## 项目备注 1、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用! 2、本项目适合计算机相关专业(如计科、人工智能、通信工程、自动化、电子信息等)的在校学生、老师或者企业员工下载学习,也适合小白学习进阶,当然也可作为毕设项目、课程设计、作业、项目初期立项演示等。 3、如果基础还行,也可在此代码基础上进行修改,以实现其他功能,也可用于毕设、课设、作业等。 下载后请首先打开README.md文件(如有),仅供学习参考, 切勿用于商业用途。 该资源内项目源码是个人的课程设计,代码都测试ok,都是运行成功后才上传资源,答辩评审平均分达到96分,放心下载使用! ## 项目备注 1、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用! 2、本项目适合计算机相关专业(如计科、人工智能、通信工程、自动化、电子信息等)的在校学生、老师或者企业员工下载学习,也适合小白学习进阶,当然也可作为毕设项目、课程设计、作业、项目初期立项演示等。 3、如果基础还行,也可在此代码基础上进行修改,以实现其他功能,也可用于毕设、课设、作业等。 下载后请首先打开README.md文件(如有),仅供学习参考, 切勿用于商业用途。
该资源内项目源码是个人的课程设计,代码都测试ok,都是运行成功后才上传资源,答辩评审平均分达到96分,放心下载使用! ## 项目备注 1、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用! 2、本项目适合计算机相关专业(如计科、人工智能、通信工程、自动化、电子信息等)的在校学生、老师或者企业员工下载学习,也适合小白学习进阶,当然也可作为毕设项目、课程设计、作业、项目初期立项演示等。 3、如果基础还行,也可在此代码基础上进行修改,以实现其他功能,也可用于毕设、课设、作业等。 下载后请首先打开README.md文件(如有),仅供学习参考, 切勿用于商业用途。 该资源内项目源码是个人的课程设计,代码都测试ok,都是运行成功后才上传资源,答辩评审平均分达到96分,放心下载使用! ## 项目备注 1、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用! 2、本项目适合计算机相关专业(如计科、人工智能、通信工程、自动化、电子信息等)的在校学生、老师或者企业员工下载学习,也适合小白学习进阶,当然也可作为毕设项目、课程设计、作业、项目初期立项演示等。 3、如果基础还行,也可在此代码基础上进行修改,以实现其他功能,也可用于毕设、课设、作业等。 下载后请首先打开README.md文件(如有),仅供学习参考, 切勿用于商业用途。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值