#include<iostream>
using namespace std;int k, n;char a[105][105];//迷宫数组 int ha, la, hb, lb;//入口、出口
bool vst[105][105];//标记数组
bool success = false;voiddfs(int x,int y){
//无路可走 -> 回溯 if(a[x][y]=='#')return;if(x <0|| y <0|| x >= n || y >= n)return;//找到出口 -> 结束 if(x == hb && y == lb){
success = true;return;}//来过这里 -> 回溯 if(vst[x][y])return;//到此一游,标记
vst[x][y]= true;//朝四个方向搜索dfs(x -1, y);dfs(x +1, y);dfs(x, y -1);dfs(x, y +1);}intmain(){
cin >> k;while(k--){
cin >> n;for(int i =0; i < n; i ++){
for(int j =0; j < n; j ++){
cin >> a[i][j];
vst[i][j]= false;}}
cin >> ha >> la >> hb >> lb;
success = false;dfs(ha, la);if(success) cout <<"YES"<< endl;else cout <<"NO"<< endl;}return0;}
1216 红与黑
#include<iostream>
using namespace std;int w, h, cnt;char a[30][30];
bool vst[30][30];voiddfs(int x,int y){
if(a[x][y]=='#')return;if(x ==0|| y ==0|| x == h+1|| y == w+1)return;if(vst[x][y])return;
vst[x][y]= true;
cnt++;dfs(x -1, y);dfs(x +1, y);dfs(x, y -1);dfs(x, y +1);}intmain(){
while(cin >> w >> h){
if(w==0&& h==0)break;int x, y;for(int i =1; i <= h; i ++){
for(int j =1; j <= w; j ++){
cin >> a[i][j];
vst[i][j]= false;if(a[i][j]=='@'){
x = i; y = j;}}}
cnt =0;dfs(x, y);
cout << cnt << endl;}return0;}
1212 LETTERS
#include<iostream>
using namespace std;int r, s, cnt, maxx;char a[30][30];
bool vst[26];voiddfs(int x,int y){
if(x ==0|| y ==0|| x == r+1|| y == s+1)return;//曾经经过相同的字母 -> 回溯 int t = a[x][y]-'A';if(vst[t])return;//标记:已访问该字母
vst[t]= true;//打擂台
maxx =max(maxx,++cnt);//朝四个方向搜索 dfs(x -1, y);dfs(x +1, y);dfs(x, y -1);dfs(x, y +1);//回溯寻找下一个解。恢复之前的状态,并把计数器减 1
vst[t]= false;
cnt--;}intmain(){
cin >> r >> s;for(int i =1; i <= r; i ++){
for(int j =1; j <= s; j ++){
cin >> a[i][j];}}dfs(1,1);
cout << maxx;return0;}
1219 马走日
#include<iostream>#include<cstring>
using namespace std;int t, n, m, x, y, cnt, step, maxx;
bool vst[15][15];int dx[8]={
-2,-1,+1,+2,+2,+1,-1,-2};int dy[8]={
+1,+2,+2,+1,-1,-2,-2,-1};voiddfs(int x,int y){
if(x <0|| y <0|| x >= n || y >= m || vst[x][y])return;if(step == n*m){
cnt ++;return;}
vst[x][y]= true;
step ++;for(int i =0; i <8; i ++){
dfs(x+dx[i], y+dy[i]);}
step --;
vst[x][y]= false;}intmain(){
int t;
cin >> t;while(t--){
cin >> n >> m >> x >> y;memset(vst, false,sizeof(vst));
cnt =0;
step =1;dfs(x, y);
cout << cnt << endl;}return0;}
1317 组合的输出
#include<iostream>#include<cstdio>
using namespace std;int n, r, ans[30];
bool vst[30];voiddfs(int x){
if(x > r){
for(int i =1; i <= r; i ++)printf("%3d", ans[i]);
cout << endl;return;}for(int i = ans[x-1]+1; i <= n; i ++){
if(!vst[i]){
vst[i]= true;
ans[x]= i;dfs(x +1);
vst[i]= false;}}}intmain(){
cin >> n >> r;dfs(1);return0;}
1318 自然数的拆分
#include<iostream>
using namespace std;constint N =1e5+10;int n, sum, ans[N];voiddfs(int x){
//完成拆分 ,结束if(sum == n){
cout << n <<'='<< ans[1];for(int i =2; i < x; i ++) cout <<'+'<< ans[i];
cout << endl;return;}// i 既要大于等于 1,又要大于等于第 x-1 个数 // i 既要小于 n,又要小于等于 n-sum for(int i =max(1, ans[x-1]); i <=min(n-1, n-sum); i ++){
//记录第 x 个数字为 i,累加
ans[x]= i;
sum += i;//搜索下一个位置上的数字 dfs(x +1);//回溯寻找下一个解,恢复之前的状态
sum -= i;}}intmain(){
cin >> n;dfs(1);return0;}
1222 放苹果
#include<iostream>
using namespace std;int t, m, n;int cnt, sum, a[15];voiddfs(int x){
if(x > n){
if(sum == m) cnt ++;return;}for(int i = a[x-1]; i <= m-sum; i ++){
a[x]= i;
sum += i;dfs(x +1);
sum -= i;}}intmain(){
cin >> t;while(t--){
cin >> m >> n;
sum =0;
cnt =0;dfs(1);
cout << cnt << endl;}return0;}
1214 八皇后
#include<iostream>
using namespace std;int n, b, cnt;int col[10];//第 1 行的皇后放在第 col[1] 列,以此类推
bool used[10];//某一列是否已有皇后//第x行 voiddfs(int x){
if(x >8){
cnt ++;if(cnt == b){
//输出一个皇后串 for(int i =1; i <=8; i ++) cout << col[i];
cout << endl;}return;}//从第 1 列到第 8 列中,搜索出能够放置皇后的列 for(int j =1; j <=8; j ++){
//如果第 j 列已经有皇后了,则不能放置下一个皇后 if(used[j])continue;
bool flag = true;for(int k =1; k < x; k ++){
//第 x 行 j 列,和第 k 行 col[k] 列是否在同一斜线上?if(x+j == k+col[k]|| x-j == k-col[k]){
flag = false;break;}}//第 j 列可以放置皇后 if(flag){
col[x]= j;//标记:第 j 列上放置了皇后
used[j]= true;//搜索下一行 dfs(x +1);//恢复状态
used[j]= false;}}}intmain(){
cin >> n;while(n--){
cin >> b;
cnt =0;//从第一行开始搜索dfs(1);}return0;}
1217 棋盘问题
#include<iostream>#include<cstring>
using namespace std;int n, k;char a[10][10];
bool used[10];//cnt表示已经放下的棋子数量 //ans表示已经找到的方案数量 int ans =0, cnt =0;voiddfs(int x){
if(cnt == k){
ans ++;return;}//从第 x 行~第 n 行,第 1 列~第 n 列,寻找放置下一个棋子 for(int i = x; i <= n; i ++){
for(int j =1; j <= n; j ++){
//判断第 i 行第 j 列能否放置棋子?if(a[i][j]=='#'&&!used[j]){
cnt ++;
used[j]= true;dfs(i +1);
cnt --;
used[j]= false;}}}}intmain(){
while(cin >> n >> k){
if(n ==-1&& k ==-1)return0;for(int i =1; i <= n; i ++){
for(int j =1; j <= n; j ++){
cin >> a[i][j];}}memset(used, false,sizeof(used));
cnt = ans =0;//从第 1 行开始搜索 dfs(1);
cout << ans << endl;}return0;}
#include<iostream>#include<cstdio>
using namespace std;constint N =30;int n, cnt[N], len, maxx;
string w[N];char ch;voiddfs(int last){
for(int now =1; now ≤ n; now ++){
if(cnt[now]==2)continue;int t =-1;if(last ==0){
if(w[now][0]== ch) t =0;}else{
for(int i = w[last].size()-1; i >0; i --){
string s = w[last].substr(i);//如果条件满足,则 s 是相连两个单词的重合部分,t是重合部分的长度 if(w[now].find(s)==0){
t = w[last].size()- i;break;}}}if(t ==-1)continue;
len += w[now].size()- t;
maxx =max(maxx, len);
cnt[now]++;dfs(now);
cnt[now]--;
len -= w[now].size()- t;}}intmain(){
cin >> n;for(int i =1; i ≤ n; i ++) cin >> w[i];
cin >> ch;dfs(0);
cout << maxx;return0;}
1221 分为互质组 (没使用搜索)
#include<iostream>#include<vector>
using namespace std;int n, x;
vector<vector<int>> group;intgcd(int x,int y){
if(y ==0)return x;returngcd(y, x%y);}intmain(){
cin >> n;
cin >> x;
vector<int> a;
a.push_back(x);
group.push_back(a);for(int i =2; i <= n; i ++){
cin >> x;
bool f1 = true;for(int i =0; i < group.size(); i ++){
bool f2 = true;for(int j =0; j < group[i].size(); j ++){
if(gcd(x, group[i][j])!=1){
f2 = false;break;}}//如果和第 i 组的数字都互质,就放入第 i 组 if(f2){
group[i].push_back(x);
f1 = false;break;}}//如果无法放到前面的任何一组中,则作为新的一组 if(f1){
a.clear();
a.push_back(x);
group.push_back(a);}}
cout << group.size();return0;}