并查集
#include <bits/stdc++.h>
using namespace std;
const int N=100010;
int p[N];
int find(int x){//返回x的祖宗节点+路径压缩
if(p[x]!=x) p[x]=find(p[x]);//把x连到祖宗节点上(路径压缩)
return p[x];
}
void merge(int x,int y){
p[find(x)]=find(y);//y的祖宗变成了x祖宗的爹
}
int main(){
int n,m;
cin>>n>>m;
for(int i=0;i<n;i++) p[i]=i;//各自为一个集合
char op;
int a,b;
while(m--){
cin>>op>>a>>b;
if(op=='M') merge(a,b);
else if(op=='Q') {
if(find(a)==find(b)) cout<<"Yes"<<endl;
else cout<<"No"<<endl;
}
}
return 0;
}
连通块中点的数量
求集合中点的数量
#include <bits/stdc++.h>
using namespace std;
const int N=100010;
int p[N],s[N];
int find(int x){//返回x的祖宗节点+路径压缩
if(p[x]!=x) p[x]=find(p[x]);//把x连到祖宗节点上(路径压缩)
return p[x];
}
void merge(int x,int y){
s[find(y)] += s[find(x)];//改祖宗节点集合的大小
p[find(x)]=find(y);//先增加集合的大小,再改变父节点
}
int main(){
int n,m;
cin>>n>>m;
for(int i=1;i<=n;i++)
{
p[i]=i;//各自为一个集合
s[i]=1;
}
string op;
int a,b;
while(m--){
cin>>op;
if(op=="C")
{
cin>>a>>b;
if(find(a)!=find(b)) merge(a,b);
}
else if(op=="Q1") {
cin>>a>>b;
if(find(a)==find(b)) cout<<"Yes"<<endl;
else cout<<"No"<<endl;
}
else if(op=="Q2")
{
cin>>a;
cout<<s[find(a)]<<endl;
}
}
return 0;
}
字符串哈希
给定一个长度为 n 的字符串,再给定 m 个询问,每个询问包含四个整数 l1,r1,l2,r2,请你判断 [l1,r1] 和 [l2,r2] 这两个区间所包含的字符串子串是否完全相同。
#include <iostream>
#include <algorithm>
using namespace std;
typedef long long ll;
const int N=100010, P=131;//P通常为131 ,大P
char str[N];
ll h[N];//哈希值
ll p[N];//预处理
ll get(int l,int r){
return h[r]-h[l-1]*p[r-l+1];//一段区间的哈希值 ,用来判断与其他区间是否相同
}
int main(){
int n,m;
cin>>n>>m>>str+1;
p[0]=1;
for(int i=1;i<=n;i++){
h[i]=h[i-1]*P+str[i];//哈希值的设定
p[i]=p[i-1]*P;//预处理
}
while(m--){
int l1,r1,l2,r2;
cin>>l1>>r1>>l2>>r2;
if(get(l1,r1)==get(l2,r2)) cout<<"Yes"<<endl;
else cout<<"No"<<endl;
}
return 0;
}
n-皇后(dfs)
#include <bits/stdc++.h>
using namespace std;
const int N=15;
int n;
char g[N][N];
bool h[N],d[N],ud[N];//行,对角线,反对角线
void dfs(int u){//i为行,u为列
if(u==n) {
for(int i=0;i<n;i++) puts(g[i]);
puts("");
return ;
}
for(int i=0;i<n;i++){
if(!h[i]&&!d[i-u+n]&&!ud[i+u]){
g[i][u]='Q';
h[i]=d[i-u+n]=ud[i+u]=true;
dfs(u+1);
h[i]=d[i-u+n]=ud[i+u]=false;
g[i][u]='.';//还原现场
}
}
}
int main(){
cin>>n;
for(int i=0;i<n;i++)
for(int j=0;j<n;j++)
g[i][j]='.';
dfs(0);
return 0;
}
迷宫问题(bfs)
#include <cstring>
#include <iostream>
#include <algorithm>
#include <queue>
using namespace std;
typedef pair<int, int> PII;
const int N = 110;
int n, m;
int g[N][N], d[N][N];
bool st[N][N];
int bfs()
{
queue<PII> q;
memset(d, 0x3f, sizeof d);
d[0][0] = 0;
q.push({0, 0});
int dx[4] = {-1, 0, 1, 0}, dy[4] = {0, -1, 0, 1};
while (!q.empty())
{
auto t = q.front();
q.pop();
for (int i = 0; i < 4; i ++ )
{
int x = t.first + dx[i], y = t.second + dy[i];
if (x >= 0 && x < n && y >= 0 && y < m && g[x][y] == 0 && !st[x][y] )
{
d[x][y] = min(d[x][y],d[t.first][t.second] + 1);
q.push({x, y});
st[x][y]=true;
}
}
}
return d[n - 1][m - 1];
}
int main()
{
cin >> n >> m;
for (int i = 0; i < n; i ++ )
for (int j = 0; j < m; j ++ )
cin >> g[i][j];
cout << bfs() << endl;
return 0;
}