首页 > 其他分享 >P7775 [COCI2009-2010#2] VUK 题解

P7775 [COCI2009-2010#2] VUK 题解

时间:2023-11-18 21:27:05浏览次数:39  
标签:q1 P7775 const int 题解 VUK && ans 510

链接

这道题卡了我 $40$ 多分钟。

其实就是跑两遍广搜,第一遍算出每个点距离树的最小距离,第二遍开个优先队列,算出逃回窝的途中最大可能的离它最近的树的距离的最小值。

接下来重点讲一下第二遍广搜。

首先,我们要知道,如果我们用 queue ,那么最先到的点不一定是最优的。

所以,我们需要用 priority_queue,来进行对下一层节点的扩展。

具体定义如下:

struct node{
	int x,y,d;// d表示,离点{x,y}最近的树的距离的最小值
	bool operator < (const node &tmp) const{
		return d<tmp.d;
	}//比较方式,距离大的先扩展
};
priority_queue<node> q1;

广搜部分就很简单了:

int ans=0x3f3f3f3f;
	while(!q1.empty()){
		st h=q1.top();
		q1.pop();
		if(h.x==edx&&h.y==edy){
			ans=min(ans,h.d);
		}
		for(int i=0;i<4;i++){
			int dx=h.x+dirx[i],dy=h.y+diry[i];
			if(dx>=1&&dx<=n&&dy>=1&&dy<=m&&!vis[dx][dy]){
				vis[dx][dy]=1;
				q1.push({dx,dy,min(h.d,cnt[dx][dy])});
			}
		}
	}

总体代码如下(有人敢直接ctj吗):

#include<bits/stdc++.h>
using namespace std;
#define reg register
int d[510][510];
char a[510][510];
int stx,sty,edx,edy;
queue<pair<int,int>> q;
int vis[510][510],cnt[510][510];
int dirx[4]={0,0,-1,1},diry[4]={1,-1,0,0};
int ans[510][510];
struct node{
	int x,y,d;
	bool operator < (const node &tmp) const{
		return d<tmp.d;
	}
};
priority_queue<node> q1;
int main()
{
	int n,m;
	cin>>n>>m;
	for(int i=1;i<=n;i++) 
		for(int j=1;j<=m;j++)
			d[i][j]=0x3f3f3f3f;
	for(int i=1;i<=n;i++)
	{
		for(int j=1;j<=m;j++){
			cin>>a[i][j];
			if(a[i][j]=='+')
			{
				q.push({i,j});
				cnt[i][j]=0;
				vis[i][j]=1;
			}
			if(a[i][j]=='V') stx=i,sty=j;
			if(a[i][j]=='J') edx=i,edy=j;
		}
	}
	while(!q.empty())
	{
		int x=q.front().first,y=q.front().second;
		q.pop();
		for(int i=0;i<4;i++)
		{
			int dx=x+dirx[i],dy=y+diry[i];
			if(dx>=1&&dx<=n&&dy>=1&&dy<=m&&!vis[dx][dy])
			{
				cnt[dx][dy]=cnt[x][y]+1;
				vis[dx][dy]=1;
				q.push({dx,dy});
			}
		}
	}
	memset(vis,0,sizeof(vis));
	q1.push({stx,sty,cnt[stx][sty]});
	vis[stx][sty]=1; 
	
	int ans=0x3f3f3f3f;
	while(!q1.empty()){
		node g=q1.top();
		q1.pop();
		if(g.x==edx&&g.y==edy){
			ans=min(ans,g.d);
		}
		for(int i=0;i<4;i++){
			int dx=g.x+dirx[i],dy=g.y+diry[i];
			if(dx>=1&&dx<=n&&dy>=1&&dy<=m&&!vis[dx][dy]){
				vis[dx][dy]=1;
				q1.push({dx,dy,min(g.d,cnt[dx][dy])});
			}
		}
	}
	cout<<ans;
	return 0;
}

标签:q1,P7775,const,int,题解,VUK,&&,ans,510
From: https://www.cnblogs.com/IOIAKmerlin/p/17832509.html

相关文章

  • CF391D1题解
    题目链接题意简述给出若干条平面上线段,找出最大的正+形边长多少。思路不难,但是判断两直线相交要考虑全面。数据不大不多,暴力直接过了。代码#include<bits/stdc++.h>usingnamespacestd;typedefstructline{intsx,sy;intex,ey;};intN,M;linexl[120......
  • [ABC326D] ABC Puzzle 题解
    题目链接解法分析这个问题是一个经典的排列谜题,通过回溯算法来穷举所有可能的字符排列,然后验证是否满足行和列约束。这个解决方案可以用于解决类似的谜题,其中需要满足一定的排列条件。通过仔细考虑约束条件,可以加快解决问题的速度,减少不必要的计算。更详细的我写在代码里了。......
  • P2678 跳石头 题解
    P2678跳石头链接这道题其实很水我们二分最长距离,最后用$check$函数判断合不合法一下是核心代码$check$函数这样写:boolcheck(intx){ intlast=0,tot=0; for(inti=1;i<=n;i++){ if(a[i]-last<x)tot++; elselast=a[i]; } if(len-last<x)tot++; returntot<......
  • CF1552D题解
    CF1552D题解思路首先,$a_i$的正负不重要,如果$a_i=b_j-b_k$,那么就有$-a_i=b_k-b_j$,读入时将$a_i$全部转化为正数。若满足$a_i+a_j+\ldots+a_k$,那么就可以构造出$b$序列,否则不行。从左到右遍历一遍$a$序列,动态规划推出所有可以组成的和,并判断是否满足上式,时间复杂度$O......
  • CF985C 题解
    CF985C题解思路由题意得知,现在有$n\timesk$块木板需要组装成$n$个木桶,每个木桶由$k$块板组成,容量服从短板原理,要求容量差不得超过$I$,求最大容量和。不管采用什么方法,无疑我们首先需要将板长(数组$a$)从小到大排列。利用贪心算法。先找出与$a_0$的长度差不超过$l$的......
  • UVA10652 Board Wrapping 题解
    LinkUVA10652BoardWrappingQuestion给出\(N\)个矩形,求面积最小的凸多边形能包住所有矩形求矩形面积占凸多边形面积的百分比Solution把矩形的四个顶点拿出来,就可以转化成凸包裸题了Code#include<bits/stdc++.h>usingnamespacestd;constdoubleeps=1e-9;constd......
  • NEFU OJ Problem1487 时空乱流题解
    时空乱流Problem:ETimeLimit:1500msMemoryLimit:65535KDescription星际飞行员Alice在一次航行中遭遇了时空乱流,时空乱流将导致Alice乘坐的飞船在n个位面之间穿梭。星际宇航局管理员Bob收到了Alice的求救信号,决定在某些位面上设立监测站,当Alice进入某个已经设立监......
  • 关于maven构建tomcat服务器一直启动不了的问题解决
    以往我都是创建maven项目后自己去配置web,再通过自己配置以下信息之后,配置tomcat。最终结果是始终报错 之后摸索发现,可以在maven项目配置前将以上“maven主路径,用户设置文件,本地仓库”信息确定好。 在弹出的页面设置好后,再创建maven项目便省时很多,tomcat配置后可以使用 ......
  • 【HDU 1276】士兵队列训练问题 题解(链表+模拟)
    某部队进行新兵队列训练,将新兵从一开始按顺序依次编号,并排成一行横队,训练的规则如下:从头开始一至二报数,凡报到二的出列,剩下的向小序号方向靠拢,再从头开始进行一至三报数,凡报到三的出列,剩下的向小序号方向靠拢,继续从头开始进行一至二报数。。。,以后从头开始轮流进行一至二报数、一至......
  • T399753 counting problem(计数问题)题解
    LinkT399753countingproblem(计数问题)Question给出一个正整数\(n\),求\(AB+CD=n\)的方案数,\(A,B,C,D\)都是要求是正整数Solution考虑直接枚举\(ABCD\)显然是不切实际的那么就折半枚举设\(F_i\)表示两个数的乘积为\(i\)的方案数答案就是\(\sum\limits_{i=1......