• CCF认证题 搜索题


      栋栋最近开了一家餐饮连锁店,提供外卖服务。随着连锁店越来越多,怎么合理的给客户送餐成为了一个急需解决的问题。
      栋栋的连锁店所在的区域可以看成是一个n×n的方格图(如下图所示),方格的格点上的位置上可能包含栋栋的分店(绿色标注)或者客户(蓝色标注),有一些格点是不能经过的(红色标注)。
      方格图中的线表示可以行走的道路,相邻两个格点的距离为1。栋栋要送餐必须走可以行走的道路,而且不能经过红色标注的点。


      送餐的主要成本体现在路上所花的时间,每一份餐每走一个单位的距离需要花费1块钱。每个客户的需求都可以由栋栋的任意分店配送,每个分店没有配送总量的限制。
      现在你得到了栋栋的客户的需求,请问在最优的送餐方式下,送这些餐需要花费多大的成本。
    输入格式
      输入的第一行包含四个整数n, m, k, d,分别表示方格图的大小、栋栋的分店数量、客户的数量,以及不能经过的点的数量。
      接下来m行,每行两个整数xi, yi,表示栋栋的一个分店在方格图中的横坐标和纵坐标。
      接下来k行,每行三个整数xi, yi, ci,分别表示每个客户在方格图中的横坐标、纵坐标和订餐的量。(注意,可能有多个客户在方格图中的同一个位置)
      接下来d行,每行两个整数,分别表示每个不能经过的点的横坐标和纵坐标。
    输出格式
      输出一个整数,表示最优送餐方式下所需要花费的成本。
    样例输入
    10 2 3 3
    1 1
    8 8
    1 5 1
    2 3 3
    6 7 2
    1 2
    2 2
    6 8
    样例输出
    29
    评测用例规模与约定
      前30%的评测用例满足:1<=n <=20。
      前60%的评测用例满足:1<=n<=100。
      所有评测用例都满足:1<=n<=1000,1<=m, k, d<=n^2。可能有多个客户在同一个格点上。每个客户的订餐量不超过1000,每个客户所需要的餐都能被送到。
     
    PS:
    下面附上代码,本题的位运算太过于深奥的,本人也并没有理解什么·1含义,但是看了网上大神的代码,就先暂时贴上代码,等以后学学位运算再去解决这道题,
    但是本人感觉就是裸bfs也可以过得,
    暑假训练的时候做过一个类似的模拟+bfs标记的问题,就是赤露罗的的bfs解决,但是有点麻烦,本人不是很喜欢敲
     
    下面附上大神的代码,仅供参考
    #include<cstdio>
    #include<cmath>
    #include<cstring>
    #include<algorithm>
    #include<iostream>
    #include<queue>
    using namespace std;
    int n,m,k,d;
    short map[1005][1005],dir[4][2]={{1,0},{0,1},{-1,0},{0,-1}};
    bool within(int x,int y){
        if(x<=0||x>n||y<=0||y>n)
            return false;
        return true;
    }
    struct node{
        int x,y,step;
        node(int a=0,int b=0,int c=0){
            x=a;
            y=b;
            step=c;
        }
    };
    queue<node> q;
    long long bfs(){
        node n;
        int t=0;
        long long sum=0;
        while(!q.empty()){
            n=q.front();
            q.pop();
            int i,x,y;
            for(i=0;i<4;i++){
                x=n.x+dir[i][0];
                y=n.y+dir[i][1];
                if(within(x,y)&&!(map[x][y]&1)){
                    map[x][y]|=1;
                    if(map[x][y]&2){
                        sum+=(map[x][y]>>2)*(n.step+1);
                        t++;
                        if(t==k)
                            return sum;
                    }
                    q.push(node(x,y,n.step+1));
                }
            }
        }
    }
    int main(){
        while(scanf("%d %d %d %d",&n,&m,&k,&d)!=EOF){
            int i,j,x,y;
            memset(map,0,sizeof(map));
            for(i=0;i<m;i++){
                scanf("%d %d",&x,&y);
                map[x][y]|=1;
                q.push(node(x,y,0));
            }
            for(i=0;i<k;i++){
                scanf("%d %d %d",&x,&y,&j);
                map[x][y]=(map[x][y]|2)+(j<<2);
            }
            for(i=0;i<d;i++){
                scanf("%d %d",&x,&y);
                map[x][y]|=1;
            }
            printf("%I64d
    ",bfs());
        }
        return 0;
    }
  • 相关阅读:
    Safe3TV
    LINQ 對付 SQL Injection 的 "免費補洞策略"
    Sstart(一个批量运行的小工具)
    从CSDN 漏洞谈.NET 安全开发
    看大成天下网站安全
    discuz获取任意管理员密码漏洞利用工具vbs版
    Wfuzz(支持各种web漏洞扫描的工具)
    Apache Tomcat UTF8编码漏洞
    VS2010下如何调试Framework源代码(即FCL)
    《Practical Clojure》学习笔记[3] Clojure中程序流程控制
  • 原文地址:https://www.cnblogs.com/13224ACMer/p/4780633.html
Copyright © 2020-2023  润新知