文章目录
- N皇后
- 小朋友崇拜圈
- 全球变暖
N皇后
问题描述:N皇后问题是一个以国际象棋为背景的问题, 如何能够在 N×N 的国际象棋棋盘上放置N个皇后,使得任何一个皇后都无法直接吃掉其他的皇后?为了达到此目的,任两个皇后都不能处于同一条横行、纵行或斜线上。
- 思路:DFS,回溯法
#include<iostream>using namespace std;using ll = long long;int vis[10][10];
int n,ans;
void dfs(int dpt){if(dpt==n+1){ans++;return;}for(int i = 1;i<=n;i++){if(vis[dpt][i])continue;for(int _i = 1;_i<=n;_i++)vis[_i][i]++;for(int _i = dpt,_j = i;_i<=n&&_j<=n;_i++,_j++)vis[_i][_j]++;for(int _i = dpt,_j = i;_i>=1&&_j<=n;_i--,_j++)vis[_i][_j]++;for(int _i = dpt,_j = i;_i<=n&&_j>=1;_i++,_j--)vis[_i][_j]++;for(int _i = dpt,_j = i;_i>=1&&_j>=1;_i--,_j--)vis[_i][_j]++;dfs(dpt+1);for(int _i = 1;_i<=n;_i++)vis[_i][i]--;for(int _i = dpt,_j = i;_i<=n&&_j<=n;_i++,_j++)vis[_i][_j]--;for(int _i = dpt,_j = i;_i>=1&&_j<=n;_i--,_j++)vis[_i][_j]--;for(int _i = dpt,_j = i;_i<=n&&_j>=1;_i++,_j--)vis[_i][_j]--;for(int _i = dpt,_j = i;_i>=1&&_j>=1;_i--,_j--)vis[_i][_j]--;}}int main( ){cin>>n;dfs(1);cout<<ans<<'\n';return 0;
}
小朋友崇拜圈
班里N个小朋友,每个人都有自己最崇拜的一个小朋友(也可以是自己)。
在一个游戏中,需要小朋友坐一个圈,
每个小朋友都有自己最崇拜的小朋友在他的右手边。
求满足条件的圈最大多少人?
小朋友编号为1,2,3,…N
输入
输入第一行,一个整数N(3<N<100000)
接下来一行N个整数,由空格分开。
输出
要求输出一个整数,表示满足条件的最大圈的人数。
样例输入
9
3 4 2 5 3 8 4 6 9
样例输出
4
思路:dfs,通过时间戳dfn来计算最大环(包括自环)。
跑dfs求最大的环,可以用时间戳(dfn),将走过的地方标记一个时间戳(即第几步走到的)。
后续搜索中,每次开始时更新最小时间戳(mindfn),如果走到已经走过的点就必须停下,然后根据时间戳的合法性来更新最大值。
#include<iostream>using namespace std;
using ll = long long;
const int N = 1e5 + 9;
int n,a[N],dfn[N],idx,mindfn;int dfs(int x){dfn[x] = ++idx;if(dfn[a[x]]){if(dfn[a[x]]>=mindfn)return dfn[x]-dfn[a[x]]+1;return 0;}return dfs(a[x]);
}int main(){ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);cin>>n;int ans = 0;for(int i=1;i<=n;++i)cin>>a[i];for(int i=1;i<=n;++i){if(!dfn[i]){mindfn = idx + 1;ans = max(ans,dfs(i));}}cout<<ans<<'\n';return 0;
}
全球变暖
你有一张某海域NxN像素的照片,".“表示海洋、”#"表示陆地,如下所示:
........
.##.....
.##.....
.....##.
...####.
....###.
........
其中"上下左右"四个方向上连在一起的一片陆地组成一座岛屿。例如上图就有2座岛屿。
由于全球变暖导致了海面上升,科学家预测未来几十年,岛屿边缘一个像素的范围会被海水淹没。具体来说如果一块陆地像素与海洋相邻(上下左右四个相邻像素中有海洋),它就会被淹没。
例如上图中的海域未来会变成如下样子:
........
........
........
........
.....#..
........
........
请你计算:依照科学家的预测,照片中有多少岛屿会被完全淹没。
【输入格式】
第一行包含一个整数N。 (1 <= N <= 1000)
以下N行N列代表一张海域照片。
照片保证第1行、第1列、第N行、第N列的像素都是海洋。
【输出格式】
一个整数表示答案。
【输入样例】
7
.......
.##....
.##....
....##.
..####.
...###.
.......
【输出样例】
1
- 思路:先用dfs将不同的岛屿染上不同的颜色,然后计算最后剩下的岛屿的颜色有多少种。原先总岛屿数(即颜色数)减去剩余颜色数,得到的就是淹没的岛屿数量。
#include<iostream>
#include<stdbool.h>
using namespace std;
const int N = 1e3 +10;char mp[N][N];
int n,scc,col[N][N];
int dx[ ]={0,0,1,-1};
int dy[ ]={1,-1,0,0};
bool vis[N*N];
void dfs(int x,int y){col[x][y] = scc;for(int i=0;i<4;++i){int nx = x + dx[i],ny = y + dy[i];if(col[nx][ny] || mp[nx][ny]=='.')continue;dfs(nx,ny);}
}
int main(){static_cast<void>(ios::sync_with_stdio(0)),static_cast<void>(cin.tie(0)),cout.tie(0);cin>>n;for(int i=1;i<=n;++i)for(int j = 1;j<=n;++j)cin>>mp[i][j];for(int i=1;i<=n;++i){for(int j=1;j<=n;++j){if(col[i][j] || mp[i][j]=='.')continue;scc++;dfs(i,j);}}int ans = 0;for(int i = 1;i<=n;++i){for(int j = 1;j<=n;++j){if(mp[i][j]=='.')continue;bool tag = true;for(int k = 0;k<4;++k){int x = i + dx[k],y = j+dy[k];if(mp[x][y]=='.')tag = false;}if(tag){if(!vis[col[i][j]])ans++;vis[col[i][j]] = true;}}}cout<<scc-ans<<'\n';return 0;
}