zoukankan      html  css  js  c++  java
  • 【2012 百度之星资格赛 H:用户请求中的品牌】

    H:用户请求中的品牌

    时间限制: 
    1000ms
     
    内存限制: 
    65536kB
    描述

    馅饼同学是一个在百度工作,做用户请求(query)分析的同学,他在用户请求中经常会遇到一些很奇葩的词汇。在比方说“johnsonjohnson”、“duckduck”,这些词汇虽然看起来是一些词汇的单纯重复,但是往往都是一些特殊品牌的词汇,不能被拆分开。为了侦测出这种词的存在,你今天需要完成我给出的这个任务——“找出用户请求中循环节最多的子串”。

    输入
    输入数据包括多组,每组为一个全部由小写字母组成的不含空格的用户请求(字符串),占一行。用户请求的长度不大于100,000。
    最后一行输入为#,作为结束的标志。
    输出
    对于每组输入,先输出这个组的编号(第n组就是输出“Case n:”);然后输出这组用户请求中循环节最多的子串。如果一个用户请求中有两个循环节数相同的子串,请选择那个字典序最小的。
    样例输入
    ilovejohnsonjohnsonverymuch
    duckduckgo
    aaabbbcccisagoodcompany
    #
    样例输出
    Case 1: johnsonjohnson
    Case 2: duckduck
    Case 3: aaa


      1 #include<stdio.h>
      2 #include<string.h>
      3 #include<stdlib.h>
      4 #define MAXD 100010
      5 #define INF 0x3f3f3f3f
      6 char b[MAXD];
      7 int N, r[MAXD], sa[MAXD], rank[MAXD], height[MAXD], wa[MAXD], wb[MAXD], ws[MAXD], wv[MAXD];
      8 int best[20][MAXD], mm[MAXD], len[MAXD], first[MAXD], P;
      9 void init()
     10 {
     11     int i;
     12     for(i = 0; b[i]; i ++)
     13         r[i] = b[i];
     14     r[N = i] = 0;
     15 }
     16 int cmp(int *p, int x, int y, int l)
     17 {
     18     return p[x] == p[y] && p[x + l] == p[y + l];
     19 }
     20 int cmp1(const void *_p, const void *_q)
     21 {
     22     int i, *p = (int *)_p, *q = (int *)_q;
     23     for(i = 0; i < len[*p] && i < len[*q]; i ++)
     24     {
     25         if(r[first[*p] + i] < r[first[*q] + i])
     26             return -1;
     27         else if(r[first[*p] + i] > r[first[*q] + i])
     28             return 1;
     29     }
     30     if(i == len[*p])
     31         return -1;
     32     return 1;
     33 }
     34 void da(int n, int m)
     35 {
     36     int i, j, p, *x = wa, *y = wb, *t;
     37     memset(ws, 0, sizeof(ws[0]) * m);
     38     for(i = 0; i < n; i ++)
     39         ++ ws[x[i] = r[i]];
     40     for(i = 1; i < m; i ++)
     41         ws[i] += ws[i - 1];
     42     for(i = n - 1; i >= 0; i --)
     43         sa[-- ws[x[i]]] = i;
     44     for(j = p = 1; p < n; j *= 2, m = p)
     45     {
     46         for(p = 0, i = n - j; i < n; i ++)
     47             y[p ++] = i;
     48         for(i = 0; i < n; i ++)
     49             if(sa[i] >= j)
     50                 y[p ++] = sa[i] - j;
     51         for(i = 0; i < n; i ++)
     52             wv[i] = x[y[i]];
     53         memset(ws, 0, sizeof(ws[0]) * m);
     54         for(i = 0; i < n; i ++)
     55             ++ ws[wv[i]];
     56         for(i = 1; i < m; i ++)
     57             ws[i] += ws[i - 1];
     58         for(i = n - 1; i >= 0; i --)
     59             sa[-- ws[wv[i]]] = y[i];
     60         for(t = x, x = y, y = t, x[sa[0]] = 0, i = p = 1; i < n; i ++)
     61             x[sa[i]] = cmp(y, sa[i - 1], sa[i], j) ? p - 1 : p ++;
     62     }
     63 }
     64 void calheight(int n)
     65 {
     66     int i, j, k = 0;
     67     for(i = 1; i <= n; i ++)
     68         rank[sa[i]] = i;
     69     for(i = 0; i < n; height[rank[i ++]] = k)
     70         for(k ? -- k : 0, j = sa[rank[i] - 1]; r[i + k] == r[j + k]; k ++);
     71 }
     72 void initRMQ(int n)
     73 {
     74     int i, j, x, y;
     75     for(mm[0] = -1, i = 1; i <= n; i ++)
     76         mm[i] = (i & (i - 1)) == 0 ? mm[i - 1] + 1 : mm[i - 1];
     77     for(i = 1; i <= n; i ++)
     78         best[0][i] = i;
     79     for(i = 1; i <= mm[n]; i ++)
     80         for(j = 1; j <= n - (1 << i) + 1; j ++)
     81         {
     82             x = best[i - 1][j];
     83             y = best[i - 1][j + (1 << (i - 1))];
     84             best[i][j] = height[x] < height[y] ? x : y;
     85         }
     86 }
     87 int askRMQ(int x, int y)
     88 {
     89     int t = mm[y - x + 1];
     90     y = y - (1 << t) + 1;
     91     x = best[t][x];
     92     y = best[t][y];
     93     return height[x] < height[y] ? height[x] : height[y];
     94 }
     95 int calculate(int x, int y)
     96 {
     97     int t;
     98     x = rank[x], y = rank[y];
     99     if(x > y)
    100         t = x, x = y, y = t;
    101     ++ x;
    102     return askRMQ(x, y);
    103 }
    104 void printresult(int max)
    105 {
    106     int i, j, k;
    107     if(max == 1)
    108     {
    109         k = INF;
    110         for(i = 0; i < N; i ++)
    111             if(r[i] < k)
    112                 k = r[i];
    113         printf("%c\n", k);
    114     }
    115     else
    116     {
    117         for(i = 0; i < P; i ++)
    118             ws[i] = i;
    119         qsort(ws, P, sizeof(ws[0]), cmp1);
    120         for(i = 0, k = ws[0]; i < len[k]; i ++)
    121             printf("%c", r[first[k] + i]);
    122         printf("\n");
    123     }
    124 }
    125 void solve()
    126 {
    127     int i, j, k, p, max = 1, ans;
    128     da(N + 1, 128);
    129     calheight(N);
    130     initRMQ(N);
    131     for(i = 1; i < N; i ++)
    132         for(j = 0; j + i < N; j += i)
    133         {
    134             ans = calculate(j, j + i);
    135             k = j - (i - ans % i);
    136             ans = ans / i + 1;
    137             if(ans < max - 1 || (ans == max - 1 && calculate(k, k + i) < i))
    138                 continue;
    139             for(k = ans == max - 1 ? k : j; j - k < i; k --)
    140             {
    141                 ans = calculate(k, k + i);
    142                 ans = ans / i + 1;
    143                 if(ans < max)
    144                     break;
    145                 if(ans > max)
    146                 {
    147                     max = ans;
    148                     P = 0;
    149                 }
    150                 first[P] = k, len[P] = ans * i;
    151                 ++ P;
    152             }
    153         }
    154     printresult(max);
    155 }
    156 int main()
    157 {
    158     int t = 0;
    159     for(;;)
    160     {
    161         scanf("%s", b);
    162         if(b[0] == '#')
    163             break;
    164         printf("Case %d: ", ++ t);
    165         init();
    166         solve();
    167     }
    168     return 0;
    169 }
  • 相关阅读:
    Linux中./configure、make、make install详解
    VMware虚拟CentOS 6.5在NAT模式下配置静态IP地址及Xshell远程控制配置
    VMWare中Linux虚拟机设置静态IP上网的设置方法
    Linux下SSH远程连接断开后让程序继续运行解决办法
    弱网测试(一)
    算法的测试
    前端图片加载优化
    jpg/jpeg/png格式的区别与应用场景
    测试分类标准
    Mysql 日期与时间戳的相互转化
  • 原文地址:https://www.cnblogs.com/ismdeep/p/2529116.html
Copyright © 2011-2022 走看看