当前位置: 移动技术网 > IT编程>开发语言>C/C++ > Codeforces 1201D - Treasure Hunting Codeforces Round #577 (Div. 2)

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

2019年08月06日  | 移动技术网IT编程  | 我要评论

efataleofmemories,w580i,空间快乐吧刷人气

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

题目链接: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;
}

 

如对本文有疑问,请在下面进行留言讨论,广大热心网友会与你互动!! 点击进行留言回复

相关文章:

验证码:
移动技术网