计蒜客NOIP模拟赛4 D2T1 鬼脚图

Posted Z-Y-Y-S

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了计蒜客NOIP模拟赛4 D2T1 鬼脚图相关的知识,希望对你有一定的参考价值。

鬼脚图,又称画鬼脚,在日本称作阿弥陀签,是一种经典游戏,也是一种简易的决策方法,常常用来抽签或决定分配组合。

下图就是一张鬼脚图,其包含若干条竖线和若干条横线。请注意,横线只能水平连接相邻的两条竖线,且 在同一高度只会有一条横线

技术分享

在图的上方,我们将这 n 条竖线依次标号为 1n。以数字 3 为例,它会沿着所在的竖线下降,期间如果 遇到横线就会移动到横线的另一端,最终降落至下面的第一条竖线。上图中还标出了另外几种数字的最终位置。奇特的是,开始时每条竖线上都有一个数字,而 最终每条竖线下还是有一个数字

现在,相信你一定已经理解了鬼脚图的规则,那么我们想请你完成下面的两个任务——

  1. 读入一张有 n 条竖线和 m 条横线的鬼脚图,请你输出最下面一行的最终序列。

  2. 如果让你设计一个鬼脚图最终序列达到上面的效果,你 最少需要多少条横线

输入格式

第一行 2 个数字 n,m,表示竖线和横线的数量。

第二行 m 个数字,依次表示从高到低的横线。数字 a 的意义为,在第 a(1≤a<n)条竖线和第 a+1 条竖线间存在一条横线。

输出格式

第一行 n 个数字,表示该鬼脚图的最终序列。

第二行 1 个数字,表示最少需要多少条横线。

数据范围

对于 10% 的数据:n≤3,m≤5

对于 20% 的数据:n≤4,m≤100

对于 40% 的数据:n≤8,m≤1000

对于 60%的数据:n≤1000,m≤5000

对于 100%的数据:n≤100000,m≤1000000

样例输入

3 3
1 2 1

样例输出

3 2 1
3
对于高度从大到小的横线,等价于在最终序列中交换
最终序列开始与初始序列相同
然后模拟,交换横线端点的值

第二问,要用最少步数得到
显然就是最终序列的逆序对数
 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<algorithm>
 5 using namespace std;
 6 int n,m,a[100001],t[1000001];
 7 long long ans;
 8 void partition(int l,int r)
 9 {
10     if (l>=r)
11         return;
12     int mid=(l+r)/2;
13     partition(l,mid);
14     partition(mid+1,r);
15     int i=l,j=mid+1,k=l;
16     while(i<=mid&&j<=r)
17     {
18         if(a[i]>a[j])
19         {
20             ans=(ans+mid-i+1);
21             t[k]=a[j];
22             k++;
23             j++;
24         }
25         else
26         {
27             t[k]=a[i];
28             k++;
29             i++;
30         }
31     }
32     while(i<=mid)
33     {
34         t[k]=a[i];
35         k++;
36         i++;
37     }
38     while(j<=r)
39     {
40         t[k]=a[j];
41         k++;
42         j++;
43     }
44     for(i=l; i<=r; i++)
45         a[i]=t[i];
46 }
47 int main()
48 {int i,x;
49     cin>>n>>m;
50     for (i=1;i<=n;i++)
51     a[i]=i;
52     for (i=1;i<=m;i++)
53     {
54         scanf("%d",&x);
55         swap(a[x],a[x+1]);
56     }
57     for (i=1;i<=n;i++)
58         if (i<n)
59         printf("%d ",a[i]);
60  else cout<<a[i];
61  partition(1,n);
62  cout<<endl<<ans;
63 }

 







以上是关于计蒜客NOIP模拟赛4 D2T1 鬼脚图的主要内容,如果未能解决你的问题,请参考以下文章

火山喷发 计蒜客16862 NOIP模拟赛 概率DP

计蒜客NOIP2017提高组模拟赛day2-小区划分

计蒜客NOIP模拟赛4 D1T2小X的密室

计蒜客NOIP模拟赛4 D1T3 小X的佛光

计蒜客NOIP2017提高组模拟赛day2-直线的交点

计蒜客2017.9.9 Day1 NOIP模拟赛