第六章:双指针,BFS,和图论

目录

  • 1238. 日志统计 【双指针】
  • 1101. 献给阿尔吉侬的花束 【BFS】
  • 1113. 红与黑 【BFS】
  • 1096. 地牢大师 【BFS】
  • 1233. 全球变暖 【BFS】

1238. 日志统计 【双指针】

第六章:双指针,BFS,和图论_第1张图片
https://www.acwing.com/problem/content/1240/
第六章:双指针,BFS,和图论_第2张图片

#include
#include
#include
#include
using namespace std;
typedef pair<int,int> PII;
#define x first//时间
#define y second//id
const int N=100100;
PII P[N];
int cnt[N];
bool st[N];
int n,d,k;
int main(void)
{
     
	cin>>n>>d>>k;
	for(int i=0;i<n;i++) scanf("%d%d",&P[i].x,&P[i].y); 
	sort(P,P+n);//pair 会自动的按第一关键字排序,然后按第二关键字排序
	int i,j;
	for(i=0,j=0;i<n;i++)
	{
     
		int id=P[i].y; 
		cnt[id]++;
		while(P[i].x-P[j].x>=d)//说明时间超过了
		{
     
			cnt[P[j].y]--;//将最开始的剔除掉
			j++;//将下一个作为哨兵
		}
		if(cnt[id]>=k) st[id]=true;//是热贴
	} 
	for(int i=0;i<=100050;i++)
		if(st[i]) cout<<i<<endl;
	return 0; 
}

结构体写法:

#include
#include
#include
#include
using namespace std;
const int N=100100;
struct data
{
     
	int id;
	int t;
}Data[N];
bool cmp(data a,data b)
{
     
	return a.t<b.t;
}
bool st[N];
int ct[N];
int n,d,k;
int main(void)
{
     
	cin>>n>>d>>k;
	for(int i=0;i<n;i++) scanf("%d%d",&Data[i].t,&Data[i].id);
	sort(Data,Data+n,cmp); 
	int i,j;
	for(i=0,j=0;i<n;i++)
	{
     
		int temp=Data[i].id;
		ct[temp]++;
		while(Data[i].t-Data[j].t>=d)
		{
     
			ct[Data[j].id]--;
			j++; 
		} 
		if(ct[temp]>=k) st[temp]=true;
	}
	for(i=0;i<N;i++) if(st[i]) cout<<i<<endl;
	return 0;
} 

1101. 献给阿尔吉侬的花束 【BFS】

第六章:双指针,BFS,和图论_第3张图片
https://www.acwing.com/problem/content/1103/

#include
#include
#include
#include
#include
using namespace std;

const int N=210;

char map[N][N];
bool vis[N][N];
int dx[4]={
     -1,0,1,0};
int dy[4]={
     0,1,0,-1};
bool flag=false;
int ans;
int startx,starty;
int endx,endy;
struct node
{
     
	int x,y,step;
}Node;
int n,r,c;
void bfs(int x,int y)
{
     
    flag=false;
	vis[x][y]=true;
	Node.x=x;
	Node.y=y;
	Node.step=0;
	queue<node> q;
	q.push(Node);
	while(!q.empty())
	{
     
		node top=q.front();
		q.pop();
		if(top.x==endx&&top.y==endy)
		{
     
			cout<<top.step<<endl;
			flag=true;
			return;
		}
		for(int i=0;i<4;i++)
		{
     
			int tempx=top.x+dx[i];
			int tempy=top.y+dy[i];
			if(tempx>=1&&tempx<=r&&tempy>=1&&tempy<=c&&map[tempx][tempy]!='#'&&!vis[tempx][tempy])
			{
     
				node temp;
				vis[tempx][tempy]=true;
				temp.x=tempx;
				temp.y=tempy;
				temp.step=top.step+1;
				q.push(temp);
			}
		}
	}
}
int main(void)
{
     
	cin>>n;
	while(n--)
	{
     
	    cin>>r>>c;
		for(int i=1;i<=r;i++)
		{
     
			for(int j=1;j<=c;j++)
			{
     
				cin>>map[i][j];
				if(map[i][j]=='S')
				{
     
					startx=i;
					starty=j;
				}
				if(map[i][j]=='E')
				{
     	
					endx=i;
					endy=j;
				}
			}
		}
		memset(vis,0,sizeof vis);//初始化,避免上次的结果影响下一次
		bfs(startx,starty);
		if(!flag) cout<<"oop!"<<endl;
	}
	return 0;
}

y总的写法:

#include
#include
#include
#include
#include

#define x first
#define y second

using namespace std;

typedef pair<int,int>PII;

const int N=210;

int n,m;
char g[N][N];
int dist[N][N];

int bfs(PII start,PII end)
{
     
	queue<PII> q;
	memset(dist,-1,sizeof dist);
	
	dist[start.x][start.y]=0;
	q.push(start);
	
	int dx[4]={
     -1,0,1,0},dy[4]={
     0,1,0,-1};
	
	while(q.size())
	{
     
		auto t=q.front();
		q.pop();
		
		for(int i=0;i<4;i++)
		{
     
			int x=t.x+dx[i],y=t.y+dy[i];
			if(x<0||x>=n||y<0||y>=m) continue;//过界了
			if(g[x][y]=='#') continue;//墙
			if(dist[x][y]!=-1) continue;//走过了
			
			dist[x][y]=dist[t.x][t.y]+1;
			if(end==make_pair(x,y)) return dist[x][y];
			
			q.push({
     x,y});
		}
	}
	return -1;
}
int main(void)
{
     
	int T;
	scanf("%d",&T);
	while(T--)
	{
     
		scanf("%d%d",&n,&m);
		for(int i=0;i<n;i++) scanf("%s",g[i]);
		
		PII start,end;
		for(int i=0;i<n;i++)
			for(int j=0;j<m;j++)
				if(g[i][j]=='S') start={
     i,j};
				else if(g[i][j]=='E') end={
     i,j};
		
		int distance=bfs(start,end);
		if(distance==-1) puts("oop!");
		else printf("%d\n",distance);
	}
	return 0;
}

1113. 红与黑 【BFS】

第六章:双指针,BFS,和图论_第4张图片
https://www.acwing.com/problem/content/1115/

#include
#include
#include
#include
#include
using namespace std;

const int N=210;

int m,n;
int ans;
char map[N][N];
bool vis[N][N];
int dx[4]={
     -1,0,1,0};
int dy[4]={
     0,1,0,-1};
struct node
{
     
	int x,y;
}Node;
void bfs(int x,int y)
{
     
	Node.x=x;
	Node.y=y;
	ans=1;
	vis[x][y]=true;
	queue<node>q;
	q.push(Node);
	while(!q.empty())
	{
     
		node top=q.front();
		q.pop();
		for(int i=0;i<4;i++)
		{
     
			int tempx=top.x+dx[i];
			int tempy=top.y+dy[i];
			if(tempx>=1&&tempx<=n&&tempy>=1&&tempy<=m&&map[tempx][tempy]!='#'&&!vis[tempx][tempy]) 
			{
     
				node m;
				m.x=tempx;
				m.y=tempy;
				ans++; 
				vis[tempx][tempy]=true;
				q.push(m);
			}
		}
	}
}
int main(void)
{
     
	while(cin>>m>>n,m||n)
	{
     
		int startx,starty;
		for(int i=1;i<=n;i++)
		{
     
			for(int j=1;j<=m;j++)
			{
     
				cin>>map[i][j]; 
				if(map[i][j]=='@')
				{
     
					startx=i;
					starty=j;
				}
			}	
		}
		ans=0;
		bfs(startx,starty);
		memset(vis,0,sizeof vis);
		cout<<ans<<endl;
	}
	return 0;
}

DFS写法:

#include
#include
#include
#include
using namespace std;

const int N=25;

int n,m;
char g[N][N];
bool st[N][N];

int dx[4]={
     -1,0,1,0},dy[4]={
     0,1,0,-1};

int dfs(int x,int y)
{
     
	int cnt=1;
	
	st[x][y]=true;
	for(int i=0;i<4;i++)
	{
     
		int a=x+dx[i],b=y+dy[i];
		if(a<0||a>=n||b<0||b>=m) continue;
		if(g[a][b]!='.') continue;
		if(st[a][b]) continue;
		
		cnt+=dfs(a,b);
	}
	return cnt;
}
int main(void)
{
     
	while(cin>>m>>n,n||m)
	{
     
		for(int i=0;i<n;i++) cin>>g[i];
		
		int x,y;
		for(int i=0;i<n;i++)
			for(int j=0;j<m;j++)
			if(g[i][j]=='@')
			{
     
				x=i;
				y=j;
			}
		
		memset(st,0,sizeof st);
		cout<<dfs(x,y)<<endl;
	}
	return 0;
}

1096. 地牢大师 【BFS】

第六章:双指针,BFS,和图论_第5张图片
https://www.acwing.com/problem/content/description/1098/

#include
#include
#include
#include
#include
using namespace std;

const int N=105;

char map[N][N][N];
bool vis[N][N][N];
int dx[4]={
     -1,0,1,0};
int dy[4]={
     0,1,0,-1};
int dz[3]={
     1,0,-1};
bool flag=true;
int l,r,c;
int startx,starty,startz;
int endx,endy,endz;
struct node
{
     
	int x,y,z,step;
}Node;
void bfs(int x,int y,int z)
{
     
	vis[z][x][y]=true;
	Node.x=x;
	Node.y=y;
	Node.z=z;
	Node.step=0;
	queue<node> q;
	q.push(Node);
	while(!q.empty())
	{
     
		node top=q.front();
		q.pop();
		if(top.x==endx&&top.y==endy&&top.z==endz)
		{
     
			flag=true;
			printf("Escaped in %d minute(s).\n",top.step);
			return;
		}
		for(int j=0;j<4;j++)
		{
     
			 int tempx=top.x+dx[j];
			 int tempy=top.y+dy[j];
			 int tempz=top.z;
			 if(tempx>=1&&tempx<=r&&tempy>=1&&tempy<=c&&tempz>=1&&tempz<=l
			 &&map[tempz][tempx][tempy]!='#'
			 &&!vis[tempz][tempx][tempy])
			 {
     
			    node m;
				m.x=tempx;
				m.y=tempy;
				m.z=tempz;
				m.step=top.step+1;
				vis[tempz][tempx][tempy]=true;
				q.push(m);
			 }
		}
		int tempx=top.x;//上楼
		int tempy=top.y;
		int tempz=top.z+1;
		if(tempx>=1&&tempx<=r&&tempy>=1&&tempy<=c&&tempz>=1&&tempz<=l
		&&map[tempz][tempx][tempy]!='#'
		&&!vis[tempz][tempx][tempy])
		{
     
		    node m;
			m.x=tempx;
			m.y=tempy;
			m.z=tempz;
			m.step=top.step+1;
			vis[tempz][tempx][tempy]=true;
			q.push(m);
		}
		tempz=top.z-1;//下楼
		if(tempx>=1&&tempx<=r&&tempy>=1&&tempy<=c&&tempz>=1&&tempz<=l
		&&map[tempz][tempx][tempy]!='#'
		&&!vis[tempz][tempx][tempy])
		{
     
		    node m;
			m.x=tempx;
			m.y=tempy;
			m.z=tempz;
			m.step=top.step+1;
			vis[tempz][tempx][tempy]=true;
			q.push(m);
		}
		
	}
}
int main(void)
{
     
	while(cin>>l>>r>>c,l||r||c)
	{
     
		for(int i=1;i<=l;i++)//层数
		{
     
			for(int j=1;j<=r;j++)//行数
			{
     
				for(int k=1;k<=c;k++)//列数
				{
     
					cin>>map[i][j][k];
					if(map[i][j][k]=='S')
					{
     
						startx=j;
						starty=k;
						startz=i;
					}
					if(map[i][j][k]=='E')
					{
     
						endx=j;
						endy=k;
						endz=i;
					}
				}
			}
		}
		flag=false;
		memset(vis,0,sizeof vis);
		bfs(startx,starty,startz);
		if(!flag) cout<<"Trapped!"<<endl;
	}
	return 0;
}

y总代码:

#include
#include
#include
#include

using namespace std;

const int N=110;

struct Point
{
     
	int x,y,z;
};

int L,R,C;
char g[N][N][N];
Point q[N*N*N];
int dist[N][N][N];

int dx[6]={
     1,-1,0,0,0,0};
int dy[6]={
     0,0,1,-1,0,0};
int dz[6]={
     0,0,0,0,1,-1};

int bfs(Point start,Point end)
{
     
	int hh=0,tt=0;
	q[0]=start;
	memset(dist,-1,sizeof dist);
	dist[start.x][start.y][start.z] = 0;
	while(hh<=tt)
	{
     
		auto t=q[hh++];//取队首元素,并出队
		
		for(int i=0;i<6;i++)
		{
     
			int x=t.x+dx[i],y=t.y+dy[i],z=t.z+dz[i];
			if(x<0||x>=L||y<0||y>=R||z<0||z>=C) continue;
			if(g[x][y][z]=='#') continue;
			if(dist[x][y][z]!=-1) continue;
			
			dist[x][y][z]=dist[t.x][t.y][t.z]+1;
			if(x==end.x&&y==end.y&&z==end.z) return dist[x][y][z];
			
			q[++tt]={
     x,y,z};//入队
		}
	}
	return -1;
}
int main(void)
{
     
	while(scanf("%d%d%d",&L,&R,&C),L||R||C)
	{
     
		Point start,end;
		for(int i=0;i<L;i++)
		{
     
			for(int j=0;j<R;j++)
			{
     
				scanf("%s",g[i][j]);
				for(int k=0;k<C;k++)
				{
     
					char c=g[i][j][k];
					if(c=='S') start={
     i,j,k};
					else if(c=='E') end={
     i,j,k};
				}
			}
		}
		int distance=bfs(start,end);
		if(distance==-1) puts("Trapped!");
		else printf("Escaped in %d minute(s).\n",distance);
	}
	
	return 0;
} 

1233. 全球变暖 【BFS】

第六章:双指针,BFS,和图论_第6张图片
https://www.acwing.com/problem/content/1235/
经典的BFS,不过要写一个check()函数来判断当前块是不是挨着海的。同时记录当前一个连通块的总的块数。
总的块数-挨着海的块数等于0说明淹没了。

#include
#include
#include
#include
#include
using namespace std;

const int N=1010;

char map[N][N];
bool vis[N][N];
int dx[4]={
     -1,0,1,0};
int dy[4]={
     0,1,0,-1};
int n;
int ans1,ans2;//ans1  一个陆地总的块数  ans2一个陆地挨着海的块数 
int sum;
struct node
{
     
	int x,y;
}Node;
bool check(int x,int y)
{
     
	for(int i=0;i<4;i++)
	{
     
		int tempx=x+dx[i];
		int tempy=y+dy[i];
		if(tempx>=1&&tempx<=n&&tempy>=1&&tempy<=n&&map[tempx][tempy]=='.')
		{
     
			return true;
		}
	}
	return false;
}
void bfs(int x,int y)
{
     
	Node.x=x;
	Node.y=y;
	vis[x][y]=true;
	ans1++;
	if(check(x,y)) ans2++; 
	queue<node>q;
	q.push(Node);
	while(!q.empty())
	{
     
		node top=q.front();
		q.pop();
		for(int i=0;i<4;i++)
		{
     
			int tempx=top.x+dx[i];
			int tempy=top.y+dy[i];
			if(tempx>=1&&tempx<=n&&tempy>=1&&tempy<=n&&map[tempx][tempy]=='#'&&!vis[tempx][tempy])
			{
     
				node m;
				m.x=tempx;
				m.y=tempy;
				vis[tempx][tempy]=true;
				ans1++;
				if(check(tempx,tempy)) ans2++;
				q.push(m);
			}
		}
	}
}
int main(void)
{
     
	cin>>n;
	for(int i=1;i<=n;i++) 
	for(int j=1;j<=n;j++)
		cin>>map[i][j];
	for(int i=1;i<=n;i++)
	{
     
		for(int j=1;j<=n;j++)
		{
     
			if(map[i][j]=='#'&&!vis[i][j])
			{
     
				ans1=ans2=0;
				bfs(i,j);
				if(ans1-ans2==0) sum++;
			}
		}
	}
	cout<<sum<<endl;
	return 0;
}

y总代码:

#include 
#include 
#include 
#include 

#define x first
#define y second

using namespace std;

typedef pair<int, int> PII;

const int N = 1010;

int n;
char g[N][N];
bool st[N][N];
PII q[N * N];
int dx[4] = {
     -1, 0, 1, 0};
int dy[4] = {
     0, 1, 0, -1};

void bfs(int sx, int sy, int &total, int &bound)
{
     
    int hh = 0, tt = 0;
    q[0] = {
     sx, sy};
    st[sx][sy] = true;

    while (hh <= tt)
    {
     
        PII t = q[hh ++ ];

        total ++ ;
        bool is_bound = false;
        for (int i = 0; i < 4; i ++ )
        {
     
            int x = t.x + dx[i], y = t.y + dy[i];
            if (x < 0 || x >= n || y < 0 || y >= n) continue;  // 出界
            if (st[x][y]) continue;
            if (g[x][y] == '.')
            {
     
                is_bound = true;
                continue;
            }

            q[ ++ tt] = {
     x, y};
            st[x][y] = true;
        }

        if (is_bound) bound ++ ;
    }
}

int main()
{
     
    scanf("%d", &n);

    for (int i = 0; i < n; i ++ ) scanf("%s", g[i]);

    int cnt = 0;
    for (int i = 0; i < n; i ++ )
        for (int j = 0; j < n; j ++ )
            if (!st[i][j] && g[i][j] == '#')
            {
     
                int total = 0, bound = 0;
                bfs(i, j, total, bound);
                if (total == bound) cnt ++ ;
            }

    printf("%d\n", cnt);

    return 0;
}

你可能感兴趣的:(Acwing蓝桥杯,算法)