填数(放卡片问题),将对递归到的某一个位置,枚举0到9的卡片,看能否放得下,然后对于递归到的最后一行或者最后一列的格子,判断该行(列)是否正好为L,若不是则考虑下一张卡片,若没有合适的卡片则只能向上return,即回溯,每次回溯必须伴随恢复现场,row-,col-
ps:匿名函数方便捏,不用开全局了OvO
#include<bits/stdc++.h>
using namespace std;
//填数(放卡片问题)
int main(){
int l,n;cin>>l>>n;
vector<int>row(n+10);
vector<int>col(n+10);
long long ans=0;
auto dfs=[&](auto &&dfs,int x,int y)->void{
if(y>=n+1&&x==1){//排满,出口
ans++;//代表一种可行方法
return;
}
for(int i=0;i<=9;i++){//0到9的卡片
row[y]+=i;
col[x]+=i;
if(row[y]>l||col[x]>l){//先判断是否放得下
row[y]-=i;//恢复现场
col[x]-=i;
continue;
}
if(y==n){//判断走到最后一行时,该列的和是不是等于l
if(col[x]<l){
row[y]-=i;
col[x]-=i;
continue;
}
}
if(x==n){走到最后一列的时候,下一步不再是x+1了
if(row[y]<l){//判断该行是不是到l了
row[y]-=i;
col[x]-=i;
continue;
}
dfs(dfs,1,y+1);//到下一行的第一个格子
row[y]-=i;
col[x]-=i;
//continue;
}
else{
dfs(dfs,x+1,y);//向下走
row[y]-=i;
col[x]-=i;
//continue;
}
}
};
dfs(dfs,1,1);
cout<<ans;
}