ZOJ Problem Set - 1037

http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=37

 

思路:

由于边长采用欧几里得距离,所以从一个点出发到其斜线方向的邻点的距离为Sqrt(2)个单位。

显然,要使总长度最短,那么路过的斜线越少越好。

也就是说,在迫不得已的时候,永远都不要去选择斜线路径。(结论一)

(由于除了起点,每个点都要过一次,且只能过一次,那么就可能存在某些情况不得不走斜线)

由于在遍历所有点之后要回到起点,那么对于整个路径的前进方向来说,

(如果不走斜线)某一个方向的前进次数必须和其反方向的次数相等。(结论二)

那么,如果m和n均为奇数的时候,结论二是不会被满足的。

也就是说,在m和n均为奇数的时候,会迫不得已选择斜线。

而当m和n至少有一个偶数的时候,能轻松找到一种行进方法,在不走斜线的前提下完成任务。(结论三)

结论三包含着2个信息:

1 字面意思;

2 如果m和n均为奇数的时候,某方向及其反方向的行进次数的差值不会大于1。

根据第二点可以进一步得知,所选路径中至多选一个斜线路径。

 

综上所述,

当两者至少有一个偶数的时候,最短路径就是m*n;

否则,m*n-1+sqrt(2) = m*n+0.41。

 

#include <iostream>
#include <iomanip>

using namespace std;

int main()
{
    int m,n,loop;
    float len = 0;
    int count = 1;
    cin >> loop;
    for(;loop > 0;loop--) {
        cin >> m >>n;
        if(m < 2 || m > 50) break;
        if(n < 2 || n > 50) break;
        if(m % 2 == 0 || n % 2 == 0) {
            len = m * n;
        } else {
            len = m * n + 0.41;
        }
        cout << "Scenario #" << count++ << ":" << endl
             << setiosflags(ios::fixed) << setprecision(2)
             << len << endl << endl;
    }
    return 0;
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值