Cod sursa(job #733274)

Utilizator desoComan Andrei deso Data 11 aprilie 2012 18:27:40
Problema Perb Scor 30
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.82 kb
#include <iostream>
#include <fstream>
#include <cstring>
#include <cstdlib>
#include <string>
#include <vector>
#include <algorithm>
#include <cmath>
using namespace std;

#define INFILE "perb.in" 
#define OUTFILE "perb.out"
#define MAX 612
ifstream fin (INFILE);
ofstream fout (OUTFILE);

int s[MAX], c[MAX][MAX], n, v[4][MAX][MAX];

int getminchanges(int x, int y, int p)
{
   int changes = 0, len = (y-x+1)/p;
   for(int i=0; i<p; i++)
   {
      int maxf = 0;
      for(int j=0; j<4; j++)
           if(x+i>=p)  maxf = max(maxf, v[j][y-p+i+1][p] - v[j][x+i-p][p]);
           else   maxf = max(maxf, v[j][y-p+i+1][p]);
      changes += len - maxf;
   }
   return changes;
}

int getmin(int x, int y)
{
   int len = y-x+1;
   int minchanges = getminchanges(x, y, 1);
   for(int i=2; i*i<=len; i++)
      if( len%i==0 )
      {
         minchanges = min(minchanges, getminchanges(x, y, i));
         minchanges = min(minchanges, getminchanges(x, y, len/i));
      }
   return minchanges;
}

int main()
{
   int m;
   fin >> n >> m;
   char buf[1024];
   fin.getline(buf, 1024);
   fin.getline(buf, 1024);
   for(int i=0; i<n; i++)
      switch(buf[i])
      {
         case 'A': 
            s[i] = 0;
            break;
         case 'C':
            s[i] = 1;
            break;
         case 'G':
            s[i] = 2;
            break;
         default:
            s[i] = 3;
      }

   memset(c, 0, sizeof(c));
   memset(v, 0, sizeof(v));
   for(int i=0; i<n; i++)
   for(int p=1; p<n; p++)
   for(int j=0; j<4; j++)
      if( i>=p )  v[j][i][p] = int(s[i]==j) + v[j][i-p][p];
      else v[j][i][p] = int(s[i]==j);
   
   //getmin(4, 9);
   for(int i=0; i<n; i++)
   for(int j=i+1;j<n; j++)
      c[i][j] = c[j][i] = getmin(i, j);

   for(int i=0; i<m; i++)
   {
      int x, y;
      fin >> x >> y;
      fout << c[x-1][y-1] << endl;
   }
	
   return 0;
}