欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

Codeforces 1201D - Treasure Hunting Codeforces Round #577 (Div. 2)

程序员文章站 2022-06-23 23:10:07
网上题解比较少,自己比较弱研究了半天(已经过了),希望对找题解的人有帮助 题目链接:https://codeforc.es/contest/1201/problem/D 题意: 给你一个矩形,起始点在(1,1),在给定坐标有宝物,你要将整个图中的宝物全部拿到,而且你不能向下走(左右随意),而且只有在 ......

网上题解比较少,自己比较弱研究了半天(已经过了),希望对找题解的人有帮助

题目链接:https://codeforc.es/contest/1201/problem/d

题意: 给你一个矩形,起始点在(1,1),在给定坐标有宝物,你要将整个图中的宝物全部拿到,而且你不能向下走(左右随意),而且只有在所给出的列上你才能向上走,问最少要走多少格

#define ios ios_base::sync_with_stdio(0); cin.tie(0);
#include <cstdio>//sprintf islower isupper
#include <cstdlib>//malloc  exit strcat itoa system("cls")
#include <iostream>//pair
#include <fstream>
#include <bitset>
//#include <map>
//#include<unordered_map>  https://codeforc.es/contest/1201/problem/d
#include <vector>
#include <stack>
#include <set>
#include <string.h>//strstr substr
#include <string>
#include <time.h>//srand(((unsigned)time(null))); seed n=rand()%10 - 0~9;
#include <cmath>
#include <deque>
#include <queue>//priority_queue<int, vector<int>, greater<int> > q;//less
#include <vector>//emplace_back
//#include <math.h>
//#include <windows.h>//reverse(a,a+len);// ~ ! ~ ! floor
#include <algorithm>//sort + unique : sz=unique(b+1,b+n+1)-(b+1);+nth_element(first, nth, last, compare)
using namespace std;//next_permutation(a+1,a+1+n);//prev_permutation
#define fo(a,b,c) for(register int a=b;a<=c;++a)
#define fr(a,b,c) for(register int a=b;a>=c;--a)
#define mem(a,b) memset(a,b,sizeof(a))
#define pr printf
#define sc scanf
void swapp(int &a,int &b);
double fabss(double a);
int maxx(int a,int b);
int minn(int a,int b);
int del_bit_1(int n);
int lowbit(int n);
int abss(int a);
const long long inf=(1ll<<60);
const double e=2.718281828;
const double pi=acos(-1.0);
const int inf=(1<<29);
const double esp=1e-9;
const int mod=(int)1e9+7;
const int n=(int)2e5+10;

int dis(int a,int b)
{
    return abss(a-b);
}
int l[n],r[n],lv[n],rv[n];
struct node
{
    int x,y;
    friend bool operator<(node a,node b)
    {
        if(a.y==b.y)
            return a.x<b.x;
        return a.y<b.y;
    }
}_[n];
int is[n];

int main()
{
    int n,m,k,q,n_=0;
    sc("%d%d%d%d",&n,&m,&k,&q);
    fo(i,1,k)sc("%d%d",&_[i].y,&_[i].x);//题目中取完一行只可能停留在头和尾
    sort(_+1,_+1+k);                    //下一行进行转移就行了
    fo(i,1,k)
    {
        int tx=_[i].x,ty=_[i].y;
        n_=maxx(n_,ty);
        if(!lv[ty])lv[ty]=tx;        //预处理
        else lv[ty]=minn(tx,lv[ty]);//宝藏的最左
        if(!rv[ty])rv[ty]=tx;
        else rv[ty]=maxx(tx,rv[ty]);//宝藏的最右
    }
    fo(i,1,q)sc("%d",&is[i]),l[is[i]]=r[is[i]]=is[i];
    sort(is+1,is+1+q);              //预处理
    fo(i,1,m)if(!l[i])l[i]=l[i-1];//左邻近的安全列
    fr(i,m,1)if(!r[i])r[i]=r[i+1];//右邻近的安全列
    int posl=1,posr=1;
    long long ans=0,preresl=0,preresr=0;
    fo(i,1,n_)
    {
        if(i==1)
        {
            if(rv[i])
                ans=dis(posl,rv[i]),posl=posr=rv[i];
            preresl=preresr=ans;
        }
        else
        {
            preresl++;preresr++;//除了第一行其他只要上升了,用于转移的左右停留状态都要+1;
            if(lv[i]==0&&rv[i]==0)
                continue;
            long long resl=inf,resr=inf;
            if(l[posl])resl=min(resl,preresl+dis(posl,l[posl])+dis(l[posl],rv[i])+dis(rv[i],lv[i]));
            if(r[posl])resl=min(resl,preresl+dis(posl,r[posl])+dis(r[posl],rv[i])+dis(rv[i],lv[i]));
            if(l[posr])resl=min(resl,preresr+dis(posr,l[posr])+dis(l[posr],rv[i])+dis(rv[i],lv[i]));
            if(r[posr])resl=min(resl,preresr+dis(posr,r[posr])+dis(r[posr],rv[i])+dis(rv[i],lv[i]));
            //进行转移;
            if(l[posl])resr=min(resr,preresl+dis(posl,l[posl])+dis(l[posl],lv[i])+dis(rv[i],lv[i]));
            if(r[posl])resr=min(resr,preresl+dis(posl,r[posl])+dis(r[posl],lv[i])+dis(rv[i],lv[i]));
            if(l[posr])resr=min(resr,preresr+dis(posr,l[posr])+dis(l[posr],lv[i])+dis(rv[i],lv[i]));
            if(r[posr])resr=min(resr,preresr+dis(posr,r[posr])+dis(r[posr],lv[i])+dis(rv[i],lv[i]));
            ans=min(resl,resr);
            preresl=resl;
            preresr=resr;
            posl=lv[i];
            posr=rv[i];
        }
    }
    pr("%lld\n",ans);
    return 0;
}

/**************************************************************************************/

int maxx(int a,int b)
{
    return a>b?a:b;
}

void swapp(int &a,int &b)
{
    a^=b^=a^=b;
}

int lowbit(int n)
{
    return n&(-n);
}

int del_bit_1(int n)
{
    return n&(n-1);
}

int abss(int a)
{
    return a>0?a:-a;
}

double fabss(double a)
{
    return a>0?a:-a;
}

int minn(int a,int b)
{
    return a<b?a:b;
}