Cod sursa(job #1558636)

Utilizator stoianmihailStoian Mihail stoianmihail Data 29 decembrie 2015 14:10:11
Problema Diviz Scor 100
Compilator c Status done
Runda Arhiva de probleme Marime 1.49 kb
#include <stdio.h>
#include <string.h>

#define MOD 30103
#define Nadejde 205
#define Smerenie 100
#define MAX_SIZE 10

int N, K, A, B;
char s[Nadejde];
int d[2][Nadejde][Smerenie];
int next[MAX_SIZE][Nadejde];

void hash(int *v, int add) {
  (*v) = ((*v) + add) % MOD;
}

int main(void) {
  int c, i, j, l, result = 0;
  FILE *f = fopen("diviz.in", "r");

  fscanf(f, "%d %d %d\n%s", &K, &A, &B, s + 1);
  N = strlen(s + 1);
  fclose(f);

  /* Transformam totul in cifre. */
  for (i = 1; i <= N; i++) {
    s[i] -= '0';
  }

  /* Initializam "next". */
  for (c = 0; c < MAX_SIZE; c++) {
    for (i = N; i; i--) {
      next[c][i] = ((s[i] == c) ? i : next[c][i + 1]);
    }
  }

  /* Cazuri limita. */
  int side = 0, write = 1;
  for (c = 1; c < MAX_SIZE; c++) {
    d[write][next[c][1]][c % K] = 1;
  }

  /* Programare dinamica pe 2 linii. */
  for (l = 1; l <= B; l++) {
    side = write;
    if (l >= A) {
      for (i = 1; i <= N; i++) {
        hash(&result, d[side][i][0]);
      }
    }
    write = !side;
    for (i = l; i <= N; i++) {
      for (j = 0; j < K; j++) {
        if (d[side][i][j]) {
          for (c = 0; c < MAX_SIZE; c++) {
            if (next[c][i + 1]) {
              hash(&d[write][next[c][i + 1]][((j << 3) + (j << 1) + c) % K], d[side][i][j]);
            }
          }
        }
      }
    }
    memset(d[side], 0, sizeof(d[side]));
  }

  freopen("diviz.out", "w", stdout);
  fprintf(stdout, "%d\n", result);
  fclose(stdout);

  /// Multumim Doamne!
  puts("Doamne ajuta!");
  return 0;
}