• hdu4099(Trie)


    题意:

      给定一个长度不超过40的数字串s,求斐波那契数列的前十万项中,最小的一个前缀为s的数的下标。

    解决:

      高精度算出前十万个斐波那契数,每个取前40位,建trie,查询O(40)

    (本地建立Trie跑了20s,让我知道了为啥服务器那么贵)

      1 #include <bits/stdc++.h>
      2 
      3 int a[22000], b[22000], c[22000];
      4 int l1, l2, l3;
      5 int op[55], len;
      6 
      7 struct Node{
      8     Node *ch[10];
      9     int ans;
     10     Node()
     11     {
     12         for (int i = 0; i < 10; ++i)
     13             ch[i] = NULL;
     14         ans = -1;
     15     }
     16 };
     17 
     18 struct Trie{
     19     Node *root;
     20     void init()
     21     {
     22         root = new Node();
     23     }
     24     void trieInsert(int index)
     25     {
     26         Node *p = root;
     27         for (int i = l3; i >= std::max(l3-39, 1); --i) {
     28             if ( p -> ch[c[i]] == NULL) {
     29                 p -> ch[c[i]] = new Node();
     30                 p-> ch[c[i]] -> ans = index;
     31             }
     32             p = p ->ch[c[i]];
     33         }
     34         p -> ans = index;
     35     }
     36     int trieQuery()
     37     {
     38         Node *p = root;
     39         for (int i = 1; i <= len; ++i) {
     40             if ( p -> ch[op[i]] == NULL)
     41                 return -1;
     42             p = p -> ch[op[i]];
     43         }
     44         return p -> ans;
     45     }
     46 }tr;
     47 
     48 void add()
     49 {
     50     int carry = 0;
     51     for (int i = 1; i <= std::max(l1, l2); ++i) {
     52         c[i] = a[i] + b[i] + carry;
     53         if (c[i] >= 10) {
     54             carry = 1;
     55             c[i] -= 10;
     56         }
     57         else
     58             carry = 0;
     59     }
     60     if (carry == 1) {
     61         c[++l3] = 1;
     62     }
     63 }
     64 
     65 void init()
     66 {
     67     tr.init();
     68     memset(a, 0, sizeof a);
     69     memset(b, 0, sizeof b);
     70     memset(c, 0, sizeof c);
     71     a[++l1] = 1;
     72     b[++l2] = 1;
     73     c[++l3] = 1;
     74     tr.trieInsert(0);
     75     for (int i = 2; i < 100000; ++i) {
     76         add();
     77         tr.trieInsert(i);
     78         for (int j = 1; j <= l2; ++j) {
     79             a[j] = b[j];
     80         }
     81         for (int j = 1; j <= l3; ++j) {
     82             b[j] = c[j];
     83         }
     84         l1 = l2;
     85         l2 = l3;
     86     }
     87 }
     88 
     89 char buf[55];
     90 
     91 int main()
     92 {
     93     init();
     94     int T;
     95     scanf("%d", &T);
     96     for (int t = 1; t <= T; ++t) {
     97         scanf("%s", buf+1);
     98         len = strlen(buf+1);
     99         for (int i = 1; i <= len; ++i) {
    100             op[i] = buf[i] - '0';
    101         }
    102         printf("Case #%d: %d
    ", t, tr.trieQuery());
    103     }
    104 }
  • 相关阅读:
    主键索引和非主键索引解析
    DNS劫持、污染的原理
    B-树,B+树与B*树的优缺点比较
    CollectionUtils工具类
    maven换源
    哪些字段可以加索引?
    callable和runnable的区别
    类加载器实例化时的顺序
    28BYJ-48步进电机
    《计算机网络》读书笔记之应用层
  • 原文地址:https://www.cnblogs.com/takeoffyoung/p/4940185.html
Copyright © 2020-2023  润新知