zoukankan      html  css  js  c++  java
  • NOIP2017模拟赛 senior 6.29 T2 小T的钢琴(piano)

    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
    ",ans[0] * 1.0 / li);
    110     }
    111 
    112     return 0;
    113 }
  • 相关阅读:
    Unix命令大全
    vs2008 与 IE8出现的兼容性问题
    Java 创建文件、文件夹以及临时文件
    如何修改Wamp中mysql默认空密码
    PAT 乙级真题 1003.数素数
    Tags support in htmlText flash as3
    DelphiXE4 FireMonkey 试玩记录,开发IOS应用 还是移植
    10 Great iphone App Review sites to Promote your Apps!
    HTML tags in textfield
    Delphi XE4 IOS 开发, "No eligible applications were found“
  • 原文地址:https://www.cnblogs.com/sin-mo/p/7230812.html
Copyright © 2011-2022 走看看