虫食算

来源:互联网 发布:中国心力衰竭数据平台 编辑:程序博客网 时间:2024/05/20 11:24

这是一道很好的题目,教给了我很多暴力的剪枝方法

超链接不解释。。。。

https://www.luogu.org/problem/show?pid=1092


解释:

重构了两遍代码才A掉的,当时思路真的有问题,没办法剪枝和处理进位情况,读了一个题解描述。

好了正题

整体思路是从后向前,从上向下的依次搜索三个大数据

几个相当重要且有趣的剪枝+思路:

1.每次搜完就判断是否已经有不合法情况出现:一列三个已知不合法,例如1+1=3;已知两个数未知进位  但 进不进  都不可以满足就不合法;一列已知两个数以及进位计算后不合法。这三种情况直接return

2.重新整理一遍进位

3.在搜一个数时如果所有情况都失败则return;

4.一列已知两个数及进位情况就直接算第三个数 !!且不满足时直接return!!

5.如果不满足3.4,孩子老老实实搜吧,但是从后面往前搜会快哦

#include <cstdio>#include <iostream>#include <cstring>using namespace std;bool ff=false,d[30];int map[4][30],jw[30];int n,r[30];bool pd(){int add=0,i;for (i=n;i>=1;i--){if (r[map[1][i]]!=-1 && r[map[2][i]]!=-1 && r[map[3][i]]!=-1)    {    if (add==-1 && (r[map[1][i]]+r[map[2][i]])%n!=r[map[3][i]] && (r[map[1][i]]+r[map[2][i]]+1)%n!=r[map[3][i]])//没有已知进位         return false;    if (add!=-1)       if ((r[map[1][i]]+r[map[2][i]]+add)%n!=r[map[3][i]]) return false;//有已知进位       else add=(r[map[1][i]]+r[map[2][i]]+add)/n;}else add=-1;}return true;}int find(int i,int j)//有没有知二求三 或者是 直接不合法 {if(j==1){if (r[map[2][i]]!=-1 && r[map[3][i]]!=-1)  {  int quq=(r[map[3][i]]-r[map[2][i]]+n)%n;  if(jw[i+1]==1) quq=(quq-1+n)%n;  if (d[quq]) return -2;  else return quq;  }return -1;}else  if (j==2)  {  if (r[map[1][i]]!=-1 && r[map[3][i]]!=-1)  {  int quq=(r[map[3][i]]-r[map[1][i]]+n)%n;  if(jw[i+1]==1) quq=(quq-1+n)%n;  if (d[quq]) return -2;  else return quq;  }return -1;  }else  {  if (r[map[1][i]]!=-1 && r[map[2][i]]!=-1)  {  int quq=(r[map[2][i]]+r[map[1][i]])%n;if(jw[i+1]==1) quq=(quq+1)%n;  if (d[quq]) return -2;  else return quq;  }return -1;  }}void gx()//重新整理进位 {int i;for (i=n;i>=1;i--)if (r[map[1][i]]!=-1 && r[map[2][i]]!=-1 && jw[i+1]!=-1)  if (r[map[1][i]]+r[map[2][i]]+jw[i+1]>=n) jw[i]=1; else jw[i]=0;else return;}void dfs(int t,int x){if (ff) return;int i,j,k;if (!pd()) return;gx();if (t==0){ff=true;for (i=1;i<=n-1;i++)printf("%d ",r[i]);printf("%d ",r[i]);return;}for (k=x;k>=1;k--)for (j=1;j<=3;j++)  if (r[map[j][k]]==-1){int tmp=find(k,j);if (tmp==-1){for (i=0;i<=n-1;i++)     if (!d[i] && !ff)     {       d[i]=true;       r[map[j][k]]=i;       dfs(t-1,k);       d[i]=false;       r[map[j][k]]=-1;     }     return;}else if (tmp==-2) return;else{d[tmp]=true;r[map[j][k]]=tmp;dfs(t-1,k);d[tmp]=false;r[map[j][k]]=-1;return;}}}int main(){    int j;char l;scanf("%d\n",&n);for (j=1;j<=n;j++){scanf("%c",&l);    map[1][j]=l-'A'+1;} scanf("%d\n");for (j=1;j<=n;j++){scanf("%c",&l);    map[2][j]=l-'A'+1;}scanf("%d\n");for (j=1;j<=n;j++){scanf("%c",&l);    map[3][j]=l-'A'+1;}memset(d,0,sizeof(d));memset(r,-1,sizeof(r));memset(jw,-1,sizeof(jw));jw[n+1]=0;dfs(n,n);}


0 0
原创粉丝点击