Cod sursa(job #758529)

Utilizator daniel.dumitranDaniel Dumitran daniel.dumitran Data 15 iunie 2012 21:48:59
Problema Substr Scor 30
Compilator cpp Status done
Runda Remember Mihai Pătrașcu Marime 1.43 kb
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>

#include <map>

#define FISIN   "substr.in"
#define FISOUT  "substr.out"

int get_nr(char c) {
  if (c >= 'a' && c <= 'z') return c - 'a';
  if (c >= 'A' && c <= 'Z') return c - 'A' + 'z' - 'a';
  return c - '0' + 2 * ('z' - 'a');
}

struct TrieNode {
  TrieNode() : occ(0) { memset(kids, 0, sizeof(kids)); }

  TrieNode* getChild(int c) {
    return kids[c];
  }

  TrieNode* getOrAddChild(int c) {
    if (!kids[c])  {
      if (objs == 250000) return NULL;
      ++objs;
      kids[c] = new TrieNode;
    }
    return kids[c];
  }

  TrieNode* kids[62];
  int occ;

  static int objs;
};

int TrieNode::objs = 0;

int main() {
  FILE *fin = fopen(FISIN, "rt");
  FILE *fout = fopen(FISOUT, "wt");

  int n, k;
  int nr[16384], len;
  fscanf(fin, "%d %d", &n, &k);

  {
    char buffer[16384 * 2];
    fscanf(fin, "%s", buffer);
    len = strlen(buffer);
    for (int i = 0; i < len; ++i) {
      nr[i] = get_nr(buffer[i]);
    }
  }

  int best_len = 0;
  TrieNode* root = new TrieNode;
  for (int i = 0; i < len; ++i) {
    TrieNode* node = root;
    for (int j = 0; i + j < len; ++j) {
      node = node->getOrAddChild(nr[i + j]);
      if (!node) break;
      ++node->occ;
      if (node->occ >= k) {
	if (j + 1 > best_len)
	  best_len = j + 1;
      }
    }
  }
    
  printf("%d\n", best_len);
  fprintf(fout, "%d\n", best_len);

  fclose(fout);
  fclose(fin);
  return 0;
}