[洛谷]P1433 吃奶酪 (#搜索 -2.1)

题目描述

房间里放着n块奶酪。一只小老鼠要把它们都吃掉,问至少要跑多少距离?老鼠一开始在(0,0)点处。

输入输出格式

输入格式:

第一行一个数n (n<=15)

接下来每行2个实数,表示第i块奶酪的坐标。

两点之间的距离公式=sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2))

输出格式:

一个数,表示要跑的最少距离,保留2位小数。

输入输出样例

输入样例#1

4
1 1
1 -1
-1 1
-1 -1

输出样例#1

7.41

思路

这题需要bfs?一个dfs+剪枝就解决了。(其实就是我太弱了)

好啦,普及一下姿♂势,那就是如何用cout输出小数点后指定位数,因为题目要求保留2位小数。

setprecision()函数,作用是保留有效n位有效数字。如,对于一个浮点数1.414,如果setprecision(2),就会输出1.41。

还有一个问题,如果输入1.400001,保留2位小数,会输出1.4,后面的0会被省略。

如果我们想要让它自动补0,需要在cout之前进行补0的定义,需要用fixed。

还有,上面这些东西都要加上头文件iomanip。

cout<<fixed<<setprecision(2)<<1.400004<<endl;//输出1.40

言归正传

直接dfs肯定超时,因此要剪枝。

已经吃掉的奶酪要记录,尝试走过的路径要归位。

#include <stdio.h>
#include <math.h>
#include <iomanip>//一定要加上! 
#include <iostream>
using namespace std;
double a[1001],b[1001],len[1001][1001],minx(0x7fffff);
int n;
bool check[1001];
inline void dfs(double minn,int now,int b)//b走完多少个坐标点,now当前坐标点,minn为走到的路径长 
{
	register int i,j;
	if(minn>minx)//剪枝,如果当前路径比当前最短的长,不必继续搜了 
	{
		return;
	}
	if(b==n)//走完了 
	{
		minx=fmin(minx,minn);//更新最短路径 
		return;
	}
	for(i=1;i<=n;i++)//尝试每一种点 
	{
		if(check[i]==0)//如果这个点没有走过 
		{
			check[i]=1;//走过了 
			minn=minn+len[now][i];//当前方案路径加上这步要走的路径 
			dfs(minn,i,b+1);//尝试下一步,b+1为下一步,i为控制变量,可以当当前坐标点使用 
			check[i]=0;//走过的路要退回 
			minn=minn-len[now][i];//坐标点也要直到为0 
		}
	}
	return;
}
int main()
{
	ios::sync_with_stdio(false);
	cout.setf(ios::fixed);
	register int i,j;
	cin>>n;
	for(i=1;i<=n;i++)
	{
		cin>>a[i]>>b[i];//输入坐标点 
	}
	for(i=0;i<=n;i++)
	{
		for(j=0;j<=n;j++)
		{
			len[i][j]=sqrt((a[i]-a[j])*(a[i]-a[j])+(b[i]-b[j])*(b[i]-b[j]));//计算坐标点之间的距离 
			//cout<<len[i][j]<<' ';
		}
		//cout<<endl;
	}
	dfs(0.0,0,0);//全tm从0开始,从0层开始搜 
	if(minx==0x7fffff)//这个值都没动过,一个路径也没有 
		cout<<-1<<endl;
	else
		cout<<fixed<<setprecision(2)<<minx<<endl;//输出最短路径 
	cout.unsetf(ios::fixed); 
	return 0;
}

 

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值