- 吴易繁 的博客
(七月暑期集训)DAY14 搜索专题
- @ 2024-7-24 17:28:41
A. 小W的数独
思路
对于这道题目,我们可以从上往下,从左往右来搜索,每次传入这个数的右边,如果不是星号,再次搜索,如果是星号,从1~n遍历每个数字,如果合法,就赋值,并再次搜索,直到带到边界,计数器++,注意:因为要注意边界范围所以要加上
if(y==n+1) x++,y=1;
代码
#include<bits/stdc++.h>
using namespace std;
const int N=10;
char a[N][N];
int cnt=0,n;
bool check(int x,int y,char c){
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
if(i==x&&j==y) continue;
if(i==x||j==y||i+j==x+y||i-j==x-y){
if(a[i][j]==c) return 0;
}
}
}
return 1;
}
void dfs(int x,int y){
if(y==n+1) x++,y=1;
if(x==n+1){
cnt++;
return ;
}
if(a[x][y]!='*') dfs(x,y+1);
else{
for(int i=1;i<=n;i++){
if(!check(x,y,i+'0')) continue;
a[x][y]=i+'0';
dfs(x,y+1);
a[x][y]='*';
}
}
}
int main(){
freopen("sm.in","r",stdin);
freopen("sm.out","w",stdout);
cin>>n;
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++) cin>>a[i][j];
}
dfs(1,1);
cout<<cnt;
return 0;
}
这道题目在考试的时候知道怎么写,但写不出来,所以就放弃了,下一次一定要再写一下。
D. 小田的数字游戏
思路
对于这道题目一个一个点来遍历,遍历每一个点的时候要将其他九个点设为不能加起来的,再来再次搜索,最后将没有被设为不能加起来的点加起来即可,注意:要注意边界范围,边界范围代码具体见A. 小W的数独一题。
代码
#include<bits/stdc++.h>
using namespace std;
const int N=10,M=10;
int a[N][M],n,m,vis[N][M],res;
void zt(int x,int y,int c){
for(int i=-1;i<=1;i++)
for(int j=-1;j<=1;j++)
vis[x+i][y+j]+=c;
}
void dfs(int x,int y,int sum){
if(y==m+1) x++,y=1;
if(x==n+1){
res=max(sum,res);
return ;
}
if(vis[x][y]==0){
zt(x,y,1);
dfs(x,y+1,sum+a[x][y]);
zt(x,y,-1);
}
dfs(x,y+1,sum);
}
int main(){
freopen("num.in","r",stdin);
freopen("num.out","w",stdout);
int t;
cin>>t;
while(t--){
cin>>n>>m;
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++) cin>>a[i][j];
res=0;
dfs(1,1,0);
cout<<res<<endl;
}
return 0;
}
这道题目在考试的时候知道怎么写,但写不出来,所以就放弃了,下一次一定要再写一下。