NOIP2017模拟赛 senior 6.29 T2 小T的钢琴(piano)

Description

Input

Output

这道题思路还是比较好想的,因为题目中已经提到公共子序列长度,所以咯,最长公共子序列好不好!

But,这里我们如果只使用LCS的话那么,这里我们的时间复杂度是O(n^2)。爆了对不对?

怎么优化呢?

对于我们的比较,在这里是比较的字符串对吧,即每一坨音符。使用string可直接比较,所以常数会小一点。

更好一点的优化就是使用哈希表,我们将乐谱Little_T中的字符串哈希,转成数值,然后通过哈希值判断,将乐谱B中的无效的音符去除。这里直接比较哈希值,常数更小。

但是,我们还是不能拿满分对吧。

我们再来优化!

题目中有提到:因为小T是一个放荡不羁的作曲家,所以保证他的乐谱中每个音符都不会重复出现。

看到这里我们是不是还可以优化呢?

有了这个条件,我们可以把LCS问题传唤成LIS(最长上升子序列)问题。

预处理还是一样的,哈希,不过我这里较为简便的直接将每一个字符转换为数值后,如果继续有字符需要加入,那么我们将先前数值乘10再相加。

我们使用二分查找,将乐谱B中数值拿入Little_T中去找,找不到,跳过。

找到了,我们从这里开始使用LIS求解就好了。

  1 #include<iostream>
  2 #include<cstdio>
  3 #include<cstring>
  4 #include<algorithm>
  5 #include<cmath>
  6 #include<string>
  7 #define INT_MAX_ 0x7fffffff
  8 #define LONG_MAX_ 0x7fffffffffffffffll
  9 #define pi acos(-1)
 10 #define N 100010
 11 #define M 200010
 12 using namespace std;
 13
 14 inline int read()
 15 {
 16     int data=0,w=1;
 17     char ch=0;
 18     while(ch!=‘-‘ && (ch<‘0‘ || ch>‘9‘)) ch=getchar();
 19     if(ch==‘-‘) w=-1,ch=getchar();
 20     while(ch>=‘0‘ && ch<=‘9‘) data=data*10+ch-‘0‘,ch=getchar();
 21     return data*w;
 22 }
 23
 24 inline void write(int x)
 25 {
 26     if(x<0) putchar(‘-‘),x=-x;
 27     if(x>9) write(x/10);
 28     putchar(x%10+‘0‘);
 29 }
 30
 31 struct Data
 32 {
 33     int value,number;
 34 } data[N];
 35 inline bool my_comp(const Data &a, const Data &b)
 36 {
 37     return a.value < b.value;
 38 }
 39
 40 int b[M],ans[N];
 41 char Little[25];
 42 char str[25];
 43 int n,r;
 44
 45 int main()
 46 {
 47     freopen("piano.in","r",stdin);
 48     freopen("piano.out","w",stdout);
 49
 50     n = read();
 51     r = read();
 52     for(int i = 1; i <= n; i++)
 53     {
 54         scanf("%s",Little);
 55         int lenth = strlen(Little);
 56         data[i].number = i;
 57         data[data[i].number].value = (Little[0] - ‘A‘ + 1) * 10 + Little[1] - ‘0‘;
 58         if(lenth > 2 && Little[2] == ‘.‘)
 59         {
 60             for(int j = 3; j < lenth; j++)
 61             {
 62                 if(Little[j] == ‘(‘ || Little[j] == ‘[‘ || Little[j] == ‘{‘) break;
 63                 data[i].value = data[i].value * 10 + Little[j] - ‘0‘;
 64             }
 65         }
 66     }
 67     sort(data+1,data+1+n,my_comp);
 68     while(r--)
 69     {
 70         int li = read();
 71         for(int i = 1; i <= li; i++)
 72         {
 73             scanf("%s",str);
 74             int lenth = strlen(str);
 75             b[i] = (str[0] - ‘A‘ + 1) * 10 + str[1] - ‘0‘;
 76             if(lenth > 2 && str[2] == ‘.‘)
 77             {
 78                 for(int j = 3; j < lenth; j++)
 79                 {
 80                     if(str[j] == ‘(‘ || str[j] == ‘[‘ || str[j] == ‘{‘) break;
 81                     b[i] = b[i] * 10 + str[j] - ‘0‘;
 82                 }
 83             }
 84         }
 85         ans[0] = 0;
 86         for(int i = 1; i <= li; i++)
 87         {
 88             int left = 1, right = n;
 89             while(left < right)
 90             {
 91                 int mid = (left + right) / 2;
 92                 if(data[mid].value >= b[i])
 93                 {
 94                     right = mid;
 95                 }
 96                 else
 97                 {
 98                     left = mid + 1;
 99                 }
100             }
101             if(data[left].value != b[i]) continue;
102             if(ans[ans[0]] < data[left].number) ans[++ans[0]] = data[left].number;
103             else
104             {
105                 int aider = lower_bound(ans+1,ans+1+ans[0],data[left].number) - ans;
106                 ans[aider] = data[left].number;
107             }
108         }
109         printf("%.6lf\n",ans[0] * 1.0 / li);
110     }
111
112     return 0;
113 }
时间: 2024-10-01 06:18:24

NOIP2017模拟赛 senior 6.29 T2 小T的钢琴(piano)的相关文章

NOIP2017模拟赛 senior 6.29 T3 Gift(gift)

Description Input Output 这道题的难度相对来说并没有第二题恼火,但还是很难搞的. 那么这道题读完题目还是比较好看出这是一道背包的变形题. 因为每一份礼物都是取或者不取两个状态,所以,01背包好理解吧. 然后题目中说选到不能选为止,所以我们先将读入的礼物的价值排个序,然后从大到小我们去选取礼物,如果当前礼物价值大于剩余财富,那么我们就不能选了对吧. 于是就这样一层层的向下进行动归. 每一次我们处理当前层的DP数组,将答案加上上一层DP数组的值.这样我们就合理的处理完了整个D

NOIP2017模拟赛 senior 6.29 T1 码灵鼠(A)

Description 码零鼠是一只很喜欢mx数学的神犇,上面那个不是ta本人的样子.这天,ta在研究一个神奇的数列,这个数列是这样的: a0 = 1 an = ai + aj   (n>=1, i,j均在[0,n-1]内均匀随机) Ta想知道对于给定的n,an的期望值是多少,你能告诉ta吗? 出于ta对整数的热爱,你只需要输出答案向下取整后的值 Input 一个整数T,表示数据组数 每组数据一行,包括一个整数n Output 一个整数E(an), 这个码灵鼠难道就是传说中的洋芋= =(手动滑稽

暑假第二次考试 冲刺Noip2017模拟赛2 解题报告——五十岚芒果酱

题1 牛跑步(running) [题目描述] 新牛到部队,CG 要求它们每天早上搞晨跑,从 A 农场跑到 B 农场.从 A 农场到 B 农场中有 n-2 个路口,分别标上号,A 农场为 1 号,B 农场为 n 号,路口分别为 2...n-1 号,从 A 农场到 B 农场有很多条路径可以到达,而 CG 发现有的路口是必须经过的,即每条路径都经过的路口,CG 要把它们记录下来,这样 CG 就可以先到那个路口,观察新牛们有没有偷懒,而你的任务就是找出所有必经路口. [输入格式] 第一行两个用空格隔开的

冲刺Noip2017模拟赛7 解题报告——五十岚芒果酱

1.二叉树(binary) 1.二叉树 (binary.cpp/c/pas) [问题描述] 二叉排序树或者是一棵空树,或者是具有下列性质的二叉树: (1)若左子树不空,则左子树上所有结点的值均小于它的根结点的值: (2)若右子树不空,则右子树上所有结点的值均大于它的根结点的值: (3)左.右子树也分别为二叉排序树: (4)没有键值相等的结点. 完全二叉树:只有最下面的两层结点度能够小于2,并且最下面一层的结点 都集中在该层最左边的若干位置的二叉树. 图1中,(a)和(b)是完全二叉树,(c)和(

冲刺Noip2017模拟赛6 解题报告——五十岚芒果酱

1.ksum(ksum) [问题描述] Peter喜欢玩数组.NOIP这天,他从Jason手里得到了大小为n的一个正整数 数组. Peter求出了这个数组的所有子段和,并将这n(n+1)/2个数降序排序,他想 知道前k个数是什么. [输入格式] 输入文件名为 ksum.in. 输入数据的第一行包含两个整数 n 和 k. 接下来一行包含 n 个正整数,代表数组. [输出格式] 输出文件名为 ksum.out. 输出 k 个数,代表降序之后的前 k 个数,用空格隔开. [输入输出样例] ksum.i

冲刺Noip2017模拟赛8 解题报告——五十岚芒果酱

1.鼎纹 [问题描述] 据说鼎纹的 种制造 式是 铜模印出来的,这是我国古代劳动 智慧 的结晶.铜模印过的地 ,会留下深深的印记,经过时间的炼化,洗 练成历史的遗存. 聪明的古代劳动人民拥有一个 a 行 b 列的铜模,每个位置要么是 0(代表 这个点是平的),要么是 1(代表这个点是凸起的).他们想造 个 n 行 m 列 的鼎 ,其中每个位置也都是 0 或 1,表示经过若干 次印后,每个位置的结果. 有一些要求.铜模是不能旋转和翻转的:在印的过程当中,铜模的凸起不 能出现在鼎面的外面(平的部分是

清北学堂 NOIP2017模拟赛 越赛越心塞

连续考了一个星期发现自己真的是手感型选手,成绩全靠天意.手感好了码出200+也没什么问题,推出式子并且打出自己都不信的操作也有过.手感差了......就一个呵呵二字. 然后开始是T总让我们休息了一个星期五不考试?本来还以为自己活在梦里然后发现星期天上午没假放了心里真是MMP. 星期五好好输出了一波联赛题,早早就睡了不提. 星期六上午,母后:“今天早上直接去机房不去教室了.” 结果到八点半才开考喵喵喵? UPD:2017年9月23日 20:19:23 Day1 看完题目一脸绝望. T1是我初二普及

【mNOIP模拟赛Day 1】 T2 数颜色

题目传送门:https://www.luogu.org/problemnew/show/P3939 题外话:写完这题后本地跑了下极限数据,用时1.5s,于是马上用fread+fwrite优化至0.3s,交至OJ,跑了600+ms,好奇地去掉fread和fwrite,居然只跑了700+ms(总感觉哪里不太对劲). 此题有一个性质:对于一个点i,其有且只有一只兔子,且该兔子的颜色是唯一的.考虑到数据范围较小(兔子数量和颜色数量均$\leq 3*10^{5}$),我们可以对所有颜色开一棵线段树,维护该

NOIP模拟赛 6.29

2017-6-29 NOIP模拟赛 Problem 1 机器人(robot.cpp/c/pas) [题目描述] 早苗入手了最新的Gundam模型.最新款自然有着与以往不同的功能,那就是它能够自动行走,厉害吧. 早苗的新模型可以按照输入的命令进行移动,命令包括‘E’.‘S’.‘W’.‘N’四种,分别对应东南西北.执行某个命令时,它会向对应方向移动一个单位.作为新型机器人,它可以执行命令串.对于输入的命令串,每一秒它会按命令行动一次.执行完命令串的最后一个命令后,会自动从头开始循环.在0时刻时机器人