zoukankan      html  css  js  c++  java
  • 「JOISC 2015 Day 1」卡片占卜

    题目描述

    K 理事长是占卜好手,他精通各种形式的占卜。今天,他要用正面写着 I ,背面写着 O 的卡片占卜一下日本 IOI 国家队的选手选择情况。

    占卜的方法如下:

    1. 首先,选取五个正整数 A,B,C,D,EA,B,C,D,EA,B,C,D,E;
    2. 然后,拿出 A+B+C+D+EA+B+C+D+EA+B+C+D+E 张卡片摆成一排,从左至右摆成 AAA 张正面,BBB 张反面,CCC 张正面,DDD 张反面,EEE 张正面的形式。也就是说,从左到右依次摆 AAA 张 IBBB 张 OCCC 张 IDDD 张 OEEE 张 I
    3. 再从预先确定的 NNN 种操作中选择 111 种以上,然后按照自己喜欢的顺序进行操作,同样的操作可以进行 111 次及以上。第 iii 种操作是「把从左到右第 LiL_iLi 张卡片到第 RiR_iRi 张卡片(包括两端)翻过来」,因为需要用手操作,所以翻 111 张牌需要花费 111 秒,完成一次操作需要花费 Ri−Li+1R_i-L_i+1RiLi+1 秒;
    4. 操作后,如果所有牌都是正面朝上的,占卜就结束了。

    因为这种占卜比较费时,所以 K 理事长在占卜之前想知道占卜能否结束,如果能结束,他想知道占卜的最小耗时。

    输入格式

    第一行,五个正整数 A,B,C,D,EA,B,C,D,EA,B,C,D,E,意义如题目描述;

    第二行,一个正整数 NNN,意义如题目描述;

    接下来 NNN 行描述操作,一行两个正整数 Li,RiL_i,R_iLi,Ri,意义如题目描述。

    输出格式

    输出一行,如果占卜能够结束,则输出一个正整数,表示占卜的最小耗时;如不能,输出 −1-11。

    样例

    样例输入 1

    1 2 3 4 5
    3
    2 3
    2 6
    4 10

    样例输出 1

    12

    样例说明 1

    最初的卡片序列为 IOOIIIOOOOIIIII
    先进行第二个操作,卡片序列变为 IIIOOOOOOOIIIII,花费 555 秒;
    再进行第三个操作,卡片序列变为 IIIIIIIIIIII,这个操作花费 777 秒,一共花费 121212 秒。
    可以证明,121212 秒为占卜的最小耗时,因此输出 121212。

    样例输入 2

    1 1 1 1 1
    1
    1 1

    样例输出 2

    -1

    数据范围与提示

    对于全部测试点,满足 1≤A,B,C,D,E,N≤105,1≤Li≤Ri≤A+B+C+D+E1le A,B,C,D,E,Nle 10^5,1le L_ile R_ile A+B+C+D+E1A,B,C,D,E,N105,1LiRiA+B+C+D+E。


    solution

    我们把区间改成(l-1,r] ,这样子修改一段区间就相当于从l-1走到r。

    有两个起点两个终点,那就枚举配对就行。

    当时考场我居然不会把区间转化成左开右闭的,真的很菜。

    有一点要注意:0也是一个合法的点,所以dist也得清inf

     1 #include<cstdio>
     2 #include<iostream>
     3 #include<cstdlib>
     4 #include<cstring>
     5 #include<algorithm>
     6 #include<cmath>
     7 #include<queue>
     8 #define maxn 500005
     9 #define inf 1e15
    10 #define ll long long
    11 using namespace std;
    12 int n,m,head[maxn],A,B,C,D,E,tot,flag[maxn];
    13 ll d[maxn],dis[5][5];
    14 struct node{
    15     int v,nex;
    16 }e[maxn];
    17 void lj(int t1,int t2){
    18     e[++tot].v=t2;e[tot].nex=head[t1];head[t1]=tot;
    19 }
    20 struct no{
    21     int x;ll dist;
    22 };
    23 bool operator <(no a,no b){
    24     return a.dist>b.dist;
    25 }
    26 void dij(int S){
    27     priority_queue<no>q;
    28     q.push((no){S,0});
    29     for(int i=0;i<=n;i++)d[i]=inf,flag[i]=0;d[S]=0;
    30     while(!q.empty()){
    31         no k=q.top();q.pop();
    32         if(flag[k.x])continue;
    33         flag[k.x]=1;
    34         for(int i=head[k.x];i;i=e[i].nex){
    35             if(d[e[i].v]>d[k.x]+abs(k.x-e[i].v)){
    36                 d[e[i].v]=d[k.x]+abs(k.x-e[i].v);
    37                 q.push((no){e[i].v,d[e[i].v]});
    38             }
    39         }
    40     }
    41 }
    42 int main()
    43 {
    44     scanf("%d%d%d%d%d",&A,&B,&C,&D,&E);
    45     n=A+B+C+D+E;
    46     cin>>m;
    47     for(int i=1,t1,t2;i<=m;i++){
    48         scanf("%d%d",&t1,&t2);t1--;
    49         lj(t1,t2);lj(t2,t1);
    50     }
    51     dij(A);
    52     dis[1][1]=d[A];dis[1][2]=d[A+B];dis[1][3]=d[A+B+C];dis[1][4]=d[A+B+C+D];
    53     dij(A+B);
    54     dis[2][1]=d[A];dis[2][2]=d[A+B];dis[2][3]=d[A+B+C];dis[2][4]=d[A+B+C+D];
    55     dij(A+B+C);
    56     dis[3][1]=d[A];dis[3][2]=d[A+B];dis[3][3]=d[A+B+C];dis[3][4]=d[A+B+C+D];
    57     dij(A+B+C+D);
    58     dis[4][1]=d[A];dis[4][2]=d[A+B];dis[4][3]=d[A+B+C];dis[4][4]=d[A+B+C+D];
    59     ll ans=min(dis[1][2]+dis[3][4],min(dis[1][3]+dis[2][4],dis[1][4]+dis[2][3]));
    60     if(ans>=inf)puts("-1");
    61     else cout<<ans<<endl;
    62     return 0;
    63 }
    View Code
  • 相关阅读:
    括号序列
    秘密信息
    大奖赛
    订单
    摆花
    利用spring自己实现观察者模式
    Spring操作mongo排序,限制查询记录数
    Hbse的读写过程
    使用aop记录数据库操作的执行时间
    分享一个关于jackson的Json工具类
  • 原文地址:https://www.cnblogs.com/liankewei/p/10587677.html
Copyright © 2011-2022 走看看