Cod sursa(job #779091)

Utilizator vendettaSalajan Razvan vendetta Data 16 august 2012 16:46:13
Problema Diviz Scor 0
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.71 kb
#include <iostream>
#include <fstream>

using namespace std;

ifstream f("diviz.in");
ofstream g("diviz.out");

#define nmax 205

int A, K, B, a[nmax], dp[nmax][nmax][101];
string s;
int n;
bool viz[nmax][10];

void citeste(){

   f >> K >> A >> B;
   f.get();
   getline(f,s);
   for(int i=0; i<s.size(); i++) a[i+1] = s[i] - '0';
   n = s.size();

}

void rezolva(){

   //trebuie sa aflu numarul de numere care sa fie divizibile cu K si care sa aiba intre A si B cifre
   //dp[i][j][r] = numarul de subsiruri din primele i iar a[i] sa fie a j-a cifra din numar si sa aiba restul r
   ////rest[i][j] = restul numarului avand pe a[i] ca a j-a cifra

   int rez = 0;

   for(int i=1; i<=n; i++){
      dp[i][1][a[i]%K] = 1;//numarul care incepe cu a[i] si da restul a[i] % K;
      viz[1][a[i]] = 1;
      for(int j=2; j<=B; j++){
         if (j == 1 && a[i] == 0) continue;//nacazul  cand a[i] e prima cifra din numar si e 0
         for(int i2=i-1; i2>=1; i2--){
            if (a[i2+1]==a[i] && viz[j][a[i]] == 1&& i2+1!=i){
               break;
            }
            for(int k=0; k<100; k++){
               int rest = (k * 10 + a[i]) % K;//continui pe alea ce dau restul k;; adaug noua cifra => noul rest va fi restul precedent * 10 + a[i] % K
               dp[i][j][rest] += dp[i2][j-1][k];//sa fie din primele i2 cifre sa afia j-1 cifre si sa aiba restul k;
               if (dp[i][j][rest] > 0) viz[j][a[i]] = 1;
            }
         }
      }
      for(int j=A; j<=B; j++) rez += dp[i][j][0];//, cout << dp[i][j][0] << " ";
      //cout << "\n";
   }

   g << rez << "\n";

}

int main(){

   citeste();
   rezolva();

   f.close();
   g.close();

   return 0;

}