• Skiing POJ 3037 很奇怪的最短路问题


    Skiing POJ 3037 很奇怪的最短路问题

    题意

    题意:你在一个R*C网格的左上角,现在问你从左上角走到右下角需要的最少时间.其中网格中的任意两点的时间花费可以计算出来.

    解题思路

    这个需要发现一个规律,就是从左上角到其他任意一点,无论选择哪条路径,到达该点的速度都是固定的。

    例如对于下面的一个矩阵:

    1 5 3

    6 3 5

    2 4 3

    可以发现我们想要计算数值为2的点的速度的话,$$v_2=v_12^{1-2}$$,路径是这样的$$1->6->2$$, 然后$$v_2=v_12{1-6}*2{6-2}=v_12^{1-2}$$。这样我们就可以知道其他点的速度。

    代码实现也是很奇特,这个是参考的大佬 (lhm) 同学代码,很厉害的同学,后来转了临床医学,还想和他组队打打比赛呢,不过也祝福他,能够找到自己喜欢的专业,毕竟自己也是转专业进的计算机专业,对于转专业自己也是有感受的。

    代码实现

    #include<iostream>
    #include<cstdio>
    #include<queue>
    #include<cmath>
    using namespace std;
    struct node{
    	int x,y;
    	double time;
    	bool operator < (const node& tmp) const
    	{
    		return time > tmp.time;
    	}
    };
    double v;
    int n,m;
    int book[110][110],a[110][110];
    priority_queue<node>q;
    int next[4][2]={{0,1},{0,-1},{1,0},{-1,0}};
    void bfs()
    {
    	while(!q.empty()) q.pop();
    	q.push((node){1,1,0.0});
    	while(!q.empty())
    	{
    		node t=q.top(); q.pop();
    		if(book[t.x][t.y]==1) continue;
    		book[t.x][t.y]=1;
    		if(t.x==n&&t.y==m) 
    		{
    			printf("%.2f
    ",t.time);
    			return ;
    		}
    		for(int i=0;i<4;i++)
    		{
    			int tx=t.x+next[i][0];
    			int ty=t.y+next[i][1];
    			if(tx>=1&&tx<=n&&ty<=m&&ty>=1&&book[tx][ty]==0) 
    			{
    				double tt=t.time+1.0/(pow(2.0,(a[1][1]-a[t.x][t.y]))*v);
    				q.push((node){tx,ty,tt}); //注意这里加入的点没有进行标记
    			}
    		}
    	}
    	return ;
    }
    int main()
    {
    	while(scanf("%lf%d%d", &v, &n, &m)!=EOF)
    	{
    		for(int i=1;i<=n;i++)
    		{
    			for(int j=1;j<=m;j++)
    			scanf("%d",&a[i][j]);
    		}
    		bfs();	
    	}
    	return 0;
    }
    
    欢迎评论交流!
  • 相关阅读:
    梯度消失和梯度爆炸
    BN的作用与使用过程
    百面机器学习笔记(二)
    正则表达式
    CSS Sprite
    事件绑定
    拖拽
    oncontextmenu
    鼠标跟随
    鼠标事件
  • 原文地址:https://www.cnblogs.com/alking1001/p/11600511.html
Copyright © 2020-2023  润新知