题目

K理事长很喜欢占卜,经常用各种各样的方式进行占卜。今天,他准备使用正面写着”I”,反面写着”O”的卡片为今年IOI的日本代表队占卜最终的成绩。

占卜的方法如下所示:

首先,选择5个正整数A,B,C,D,E。

将A+B+C+D+E张IOI卡片排成一行,最左侧的A张卡片正面朝上,接下来B张反面朝上,接下来C张卡片正面朝上,接下来D张反面朝上,最后E张正面朝上。如此排列的话,从左侧开始顺次为A张“I”,B张“O”,C张“I”,D张“O”,E张“I”。

在预先决定的N种操作中选出至少1种,然后按照任意顺序执行。(注:同种操作执行多次也是可以的。)这里,第i种操作(1<=i<=N)为【将从左数第Li张卡片到第Ri张卡片全部翻转】。翻转一张卡片需要1秒的时间,因此第i种操作耗时Ri-Li+1秒。

操作结束后,如果所有卡片都是正面朝上则占卜成功。K理事长不想翻多余的牌,因此在实际使用卡片占卜之前会先计算出是否存在占卜成功的可能性。进一步,如果占卜可能成功,他会计算出能使占卜成功所消耗的时间的最小值。

现在给出卡片的排列信息和预先决定的操作信息,请你写一个程序,计算出占卜能否成功,如果能成功,输出消耗时间的最小值。

分析

首先在输入的字符串的后面加一个'I',然后把字符串中的'I'变成1,'O'变成0,转换为01串。

接着将相邻的数两两异或,就可以得出一个新的序列:一堆0之中夹着4个1。

现在要将序列中的数全部变成0;

我们发现如果修改区间[L,R],实际上就是把序列中在位置L-1的和位置R的数改变一下。

那么将每个位置看作一个点,每次修改当做一条连接位置L-1的和位置R的权值为R-L+1的边。

答案就是把这4个1的位置分成两组,求出它们的最短距离之和。

  1. #include <cmath>
  2. #include <iostream>
  3. #include <cstdio>
  4. #include <cstdlib>
  5. #include <cstring>
  6. #include <algorithm>
  7. #include <queue>
  8. const long long maxlongint=214748364700000;
  9. using namespace std;
  10. long long a[10],d[2000006],n,m,ans,dis[5][500006],to[1000006],v[1000006],next[1000006],last[1000006],tot;
  11. bool bz[500006];
  12. long long bj(long long x,long long y,long long z)
  13. {
  14. next[++tot]=last[x];
  15. last[x]=tot;
  16. to[tot]=y;
  17. v[tot]=z;
  18. }
  19. long long spfa(long long x)
  20. {
  21. long long head=0,tail=1,i,j,k;
  22. memset(dis[x],43,sizeof(dis[x]));
  23. memset(bz,true,sizeof(bz));
  24. d[1]=a[x];
  25. dis[x][a[x]]=0;
  26. while(head<tail)
  27. {
  28. k=d[++head];
  29. bz[k]=true;
  30. for(i=last[k];i;i=next[i])
  31. {
  32. j=to[i];
  33. if(v[i]+dis[x][k]<dis[x][j])
  34. {
  35. dis[x][j]=dis[x][k]+v[i];
  36. if(bz[j])
  37. {
  38. bz[j]=false;
  39. d[++tail]=j;
  40. }
  41. }
  42. }
  43. }
  44. }
  45. int main()
  46. {
  47. for(long long i=1;i<=5;i++)
  48. {
  49. long long x;
  50. scanf("%lld",&x);
  51. a[i]=a[i-1]+x;
  52. }
  53. scanf("%lld",&n);
  54. for(long long i=1;i<=n;i++)
  55. {
  56. long long x,y;
  57. scanf("%lld%lld",&x,&y);
  58. bj(x-1,y,y-x+1);
  59. bj(y,x-1,y-x+1);
  60. }
  61. ans=maxlongint;
  62. for(long long i=1;i<=4;i++)
  63. spfa(i);
  64. for(long long i=1;i<=3;i++)
  65. for(long long j=i+1;j<=4;j++)
  66. for(long long k=1;k<=3;k++)
  67. if(i!=k && j!=k)
  68. for(long long l=k+1;l<=4;l++)
  69. if(l!=i && l!=j)
  70. {
  71. ans=min(ans,dis[i][a[j]]+dis[k][a[l]]);
  72. }
  73. if(ans<=2147483647000)
  74. printf("%lld\n",ans);
  75. else
  76. printf("-1\n");
  77. }

【NOIP2015模拟11.3】IOIOI卡片占卜的更多相关文章

  1. JZOJ 4298. 【NOIP2015模拟11.2晚】我的天

    4298. [NOIP2015模拟11.2晚]我的天 (File IO): input:ohmygod.in output:ohmygod.out Time Limits: 1000 ms Memor ...

  2. 【NOIP2015模拟11.5】JZOJ8月5日提高组T2 Lucas的数列

    [NOIP2015模拟11.5]JZOJ8月5日提高组T2 Lucas的数列 题目 PS:\(n*n*T*T<=10^{18}\)而不是\(10^1*8\) 题解 题意: 给出\(n\)个元素的 ...

  3. 【NOIP2015模拟11.5】JZOJ8月5日提高组T1 俄罗斯套娃

    [NOIP2015模拟11.5]JZOJ8月5日提高组T1 俄罗斯套娃 题目 题解 题意就是说 将1~\(n\)排列,问有多少种方案使得序列的逆序对个数小于\(k\) 很容易想到DP 设\(f[i][ ...

  4. 【NOIP2015模拟11.2晚】JZOJ8月4日提高组T2 我的天

    [NOIP2015模拟11.2晚]JZOJ8月4日提高组T2 我的天 题目 很久很以前,有一个古老的村庄--xiba村,村子里生活着n+1个村民,但由于历届村长恐怖而且黑暗的魔法统治下,村民们各自过着 ...

  5. 【NOIP2015模拟11.4】JZOJ2020年8月6日提高组T2 最优交换

    [NOIP2015模拟11.4]JZOJ2020年8月6日提高组T2 最优交换 题目 题解 题意 有一个长度为\(n\)的正整数 最多可以进行\(k\)次操作 每次操作交换相邻两个位置上的数 问可以得 ...

  6. 【NOIP2015模拟11.4】JZOJ8月6日提高组T1 刷题计划

    [NOIP2015模拟11.4]JZOJ8月6日提高组T1 刷题计划 题目 题解 题意 有\(n\)道题,编号为1~\(n\) 给出\(m\)次操作 每次操作有3种类型 1 \(x\) 表示交了\(A ...

  7. 【NOIP2015模拟11.5】JZOJ8月5日提高组T3 旅行

    [NOIP2015模拟11.5]JZOJ8月5日提高组T3 旅行 题目 若不存在第\(k\)短路径时,输出"Stupid Mike" 题解 题意 给出一个有\(n\)个点的树 问这 ...

  8. IOIOI卡片占卜(Atcoder-IOIOI カード占い)(最短路)

    题目描述: K 理事長は占いが好きで,いつも様々な占いをしている.今日は,表の面に ‘I’ が,裏の面に ‘O’ が書か れたカードを使って今年の IOI での日本選手団の出来を占うことにした. 占い ...

  9. 【NOIP2015模拟11.3】备用钥匙

    题目 你知道Just Odd Inventions社吗?这个公司的业务是"只不过是奇妙的发明(Just Odd Inventions)".这里简称为JOI社. JOI社有N名员工, ...

随机推荐

  1. Group by的用法

    Group by的用法 GROUP BY 语句根据一个或多个列对结果集进行分组.在分组的列上我们可以使用 COUNT, SUM, AVG,等函数. Group by用法: SELECT column_ ...

  2. Redis启动命令

    Redis的下载地址为https://github.com/MicrosoftArchive/redis/releases,Redis 支持 32 位和 64 位,根据自己的需要下载相应的版本. 下载 ...

  3. Java多线程学习——图片下载

    实现多线程方式1:继承类Thread——重写方法run——调用方法start 从网络下载图片首先要增加包commons-io.jar import org.apache.commons.io.File ...

  4. EFI系统分区如何删除

    U盘或者硬盘被做了系统安装盘. 结果在格式化都是失败,分区也不行. 有了新招 EFI分区是您的系统启动引导的分区,存放引导启动的文件的,因此它是一个操作系统独立的分区,实际上它是UEFI加载的固件和应 ...

  5. Mybatis-学习笔记(7)缓存机制

    1.一级缓存 SqlSession级别的缓存,使用HashMap存储缓存数据,不同的SqlSession之间的缓存数据区域(HashMap)互不影响. 一级缓存的作用域是SqlSession范围(强调 ...

  6. Scrapy 教程(七)-架构与中间件

    Scrapy 使用 Twisted 这个异步框架来处理网络通信,架构清晰,并且包含了各种中间件接口,可以灵活的完成各种需求. Scrapy 架构 其实之前的教程都有涉及,这里再做个系统介绍 Engin ...

  7. Vue.nextTick浅析

    Vue.nextTick浅析 Vue的特点之一就是响应式,但数据更新时,DOM并不会立即更新.当我们有一个业务场景,需要在DOM更新之后再执行一段代码时,可以借助nextTick实现.以下是来自官方文 ...

  8. PHP MVC结构系统架构设计

    今天研究了下PHP MVC结构,所以决定自己写个简单的MVC,以待以后有空再丰富.至于什么MVC结构,其实就是三个Model,Contraller,View单词的简称,,Model,主要任务就是把数据 ...

  9. HTML面试问题收集(1)

    1.浏览器页面有哪三层构成,分别是什么,作用是什么? 构成:结构层.表示层.行为层分别是:HTML.CSS.JavaScript 作用:HTML实现页面结构,CSS完成页面的表现与风格,JavaScr ...

  10. SPA(单页面应用)和MPA(多页面应用)

    话不多说,直接看图,一目了然