小白月赛22 D : 收集纸片

Posted prjruckyone

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了小白月赛22 D : 收集纸片相关的知识,希望对你有一定的参考价值。

D:收集纸片

技术图片

考察点 : 全排列,对数据范围的估计程度
坑点  : 注意算最后回到初始的那步距离

析题得侃 :

一看题目最短路,诶呦,这不是最拿手的 BFS 走最短路吗?哈哈,定睛一看
这么多目的地,这还走个茄子,但是看看这道题的数据范围, 10,这不就完完
全全的可以暴力一发了,怎么暴力呢 ? 
我们并不知道那条线路会是最优的,所以我们可以用全排列列举出每一条线路,
然后最后取最小值即可。

Code :

#include <cstdio>
#include <string>
#include <cstring>
#include <iostream>
#include <algorithm>

#define INF 0x3f3f3f3f

#define x first
#define y second

using namespace std;

const int maxn = 25;

typedef pair<int,int>PII;

int T,n,res;
int start_x,start_y,end_x,end_y;

int a[maxn];

PII P[maxn];

int main(void) {
    int dist(int x,int y);
    void solve();
    scanf("%d",&T);
    while(T --) {
        scanf("%d%d",&end_x,&end_y);
        scanf("%d%d",&start_x,&start_y);
        scanf("%d",&n);
        for(int i = 1; i <= n; i ++) {
            scanf("%d%d",&P[i].x,&P[i].y);
        }
        P[n + 1].x = start_x,P[n + 1].y = start_y;
        res = INF;
        solve();
        printf("The shortest path has length %d
",res);
    }
    return 0;
}

int dist(int ax,int ay,int bx,int by) {
    return abs(ax - bx) + abs(ay - by);
}

void solve() {
        // 拿 a 数组的不同排列作为我们走的每条线路
    for(int i = 1; i <= n; i ++) {
        a[i] = i;
    }
    do {
        int ans = 0;
        for(int i = 1; i <= n; i ++) {
            if(P[a[i]].x > end_x || P[a[i]].y > end_y) continue;
            if(i == 1) ans += dist(start_x,start_y,P[a[i]].x,P[a[i]].y);
            else ans += dist(P[a[i]].x,P[a[i]].y,P[a[i - 1]].x,P[a[i - 1]].y); 
        }
                // 回到起点
        ans += dist(start_x,start_y,P[a[n]].x,P[a[n]].y);
        res = min(res,ans);

    } while(next_permutation(a + 1,a + 1 + n));
    return ;
}

后记:

一定要观察数据范围,根据数据范围采取对应的策略

以上是关于小白月赛22 D : 收集纸片的主要内容,如果未能解决你的问题,请参考以下文章

小白月赛22 E : 方格涂色

小白月赛22 G : 仓库地址

小白月赛22 J : 计算 A + B

小白月赛54 F.Traveling(图论&构造)

小白月赛54 F.Traveling(图论&构造)

牛客小白月赛37 I 加减