一、双指针
例题
日志统计
题目信息
思路
题解
#include <bits/stdc++.h>
#define int long long
#define endl '\n'
#define maxsize 100100
using namespace std;
int n,d,k;
int cnt[maxsize];
pair <int,int> num[maxsize];
bool flag[maxsize];
signed main()
{
ios::sync_with_stdio();
cin.tie(0);
cout.tie(0);
cin>>n>>d>>k;
for(int i=0;i<n;i++)
{
cin>>num[i].first>>num[i].second;
}
sort(num,num+n);
for(int i=0,j=0;j<n;j++)
{
cnt[num[j].second]++;
while(num[j].first-num[i].first>=d)
{
cnt[num[i].second]--;
i++;
}
if(cnt[num[j].second]>=k) flag[num[j].second]=true;
}
for(int i=0;i<=100000;i++)
{
if(flag[i]) cout<<i<<endl;
}
return 0;
}
二、BFS
适合用于查找一条合法的路径或最小步数
例题
1、献给阿尔吉侬的花束
题目信息
思路
题解
#include <bits/stdc++.h>
#define endl '\n'
#define int long long
#define maxsize 210
using namespace std;
int t,r,c;
char maps[maxsize][maxsize];
int dis[maxsize][maxsize];
pair <int,int> weizhi;
int bfs(pair<int,int> start,pair<int,int> end)
{
queue<pair<int,int>> q;
memset(dis,-1,sizeof(dis));
dis[start.first][start.second]=0;
q.push(start);
int dx[4]={-1,0,1,0};
int dy[4]={0,1,0,-1};
while(!q.empty())
{
auto tmp=q.front();
q.pop();
for(int i=0;i<4;i++)
{
int x=tmp.first+dx[i];
int y=tmp.second+dy[i];
//越界的情况
if(x<0 || y<0 || x>=r || y>=c) continue;
//障碍物
if(maps[x][y]=='#') continue;
//之前已经遍历过
if(dis[x][y] != -1 ) continue;
dis[x][y]=dis[tmp.first][tmp.second]+1;
if(end==make_pair(x,y)) return dis[x][y];
q.push(make_pair(x,y));
}
}
return -1;
}
signed main()
{
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
pair<int,int> start,end;
cin>>t;
for(int i=0;i<t;i++)
{
cin>>r>>c;
for(int j=0;j<r;j++)
{
for(int k=0;k<c;k++)
{
cin>>maps[j][k];
if(maps[j][k]=='S')
{
start.first=j;
start.second=k;
}
if(maps[j][k]=='E')
{
end.first=j;
end.second=k;
}
}
}
int distance=bfs(start,end);
if(distance==-1)
{
cout<<"oop!"<<endl;
}
else{
cout<<distance<<endl;
}
}
return 0;
}
2、红与黑
题目信息
思路
题解
#include <bits/stdc++.h>
#define int long long
#define maxsize 30
using namespace std;
int h,w;
char maps[maxsize][maxsize];
bool flag[maxsize][maxsize];
queue<pair<int,int>> q;
int bfs(pair<int,int> start)
{
int count=0;
int dx[4]={-1,0,1,0};
int dy[4]={0,1,0,-1};
q.push(start);
flag[start.first][start.second]=true;
count++;
while(!q.empty())
{
auto tmp=q.front();
q.pop();
for(int i=0;i<4;i++)
{
int x=tmp.first+dx[i];
int y=tmp.second+dy[i];
if(x<0 || y<0 || x>=h || y>=w) continue;
if(maps[x][y]=='#') continue;
if(flag[x][y]==true) continue;
q.push(make_pair(x,y));
flag[x][y]=true;
count++;
}
}
return count;
}
signed main()
{
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
pair<int,int> start;
while(true)
{
cin>>w>>h;
if(w==0&&h==0) break;
for(int i=0;i<h;i++)
{
for(int j=0;j<w;j++)
{
cin>>maps[i][j];
if(maps[i][j]=='@')
{
start.first=i;
start.second=j;
}
}
}
int cnt=bfs(start);
cout<<cnt<<endl;
//恢复现场
memset(maps,0,sizeof(maps));
memset(flag,false,sizeof(flag));
}
return 0;
}
图论
例题
交换瓶子
题目信息
思路
题解
#include <bits/stdc++.h>
#define endl '\n'
#define int long long
#define maxsize 10010
using namespace std;
int n;
int a[maxsize];
bool num[maxsize];
signed main()
{
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
cin>>n;
int cnt=0;
for(int i=1;i<=n;i++) cin>>a[i];
for(int i=1;i<=n;i++)
{
if(!num[i])
{
cnt++;
for(int j=i;!num[j];j=a[j])
{
num[j]=true;
}
}
}
cout<<n-cnt<<endl;
return 0;
}