题目传送:https://www.luogu.org/problem/show?pid=1092
#include <iostream> #include <cstring> #include <cstdlib> #include <cstdio> #include <cmath> #define maxn 30 int n,flag[maxn]; ][maxn]; bool use[maxn]; int id(char ch)//将字符串转换为数字 { ; } void dfs(int x,int y,int t)//x代表列,y代表行,t代表进位 { ) //从上到下,从右到左,x==0表示搜到了最后一列 { )//最后一列不能有进位,如果进了以为则第三个字符串会比其他两个字符串长一位 { ;i<n;i++) //如果满足条件,就输出 printf("%d ",flag[i]);//输出 printf("%d\n",flag[n]);//输出 exit(); //相当于return 0;程序结束 } return;//返回 } ;i>=;i--) //剪枝1 { ][i])];//w1表示第一行字符串代表的数字 ][i])];//w2表示第二行字符串代表的数字 ][i])];//w3表示第三行字符串代表的数字 ||w2==-||w3==-) //如果这个位置上还没被赋值,就返回 continue; )%n!=w3) return; //如果无论进位与否,都不能整除对应的w3就说明字符串不匹配,直接return ; } ) ////如果这个位置上还没被赋值,就进行赋值操作 { ;i>=;i--) //倒着枚举更快 if (!use[i]) //如果这个数没有用过 { ) //且不是最后一行 { flag[id(s[y][x])]=i;//就将这个位置赋上值 use[i]=;//标记这个数用过 dfs(x,y+,t);//继续搜索下一行 flag[id(s[y][x])]=-;//还原 use[i]=;//还原 } else //当y==3时 { ][x])]+flag[id(s[][x])]+t;//两个数加上它们的进位 if (w%n!=i) continue; use[i]=;flag[id(s[][x])]=i;//赋值,标记这个数用过 dfs(x-,,w/n);//搜索下一列,进位需要改变 use[i]=;flag[id(s[][x])]=-;//还原 } } } else //如果这个位置上已经被赋值了 { ) //继续搜索 dfs(x,y+,t); else { ][x])]+flag[id(s[][x])]+t; ][x])]) //剪枝 2 return; dfs(x-,,w/n);//搜索下一列,进位需要改变 } } } int main() { scanf("%d",&n);//读入n,代表n进制等...... ;i<=;i++) scanf();//读入3行字符串 memset(flag,-,sizeof(flag));//将所有位置标记为未赋值 dfs(n,,);//从右往左,上往下搜索,所有从第n列,第1行开始 ;//结束 }