Cod sursa(job #1508461)

Utilizator tamionvTamio Vesa Nakajima tamionv Data 22 octombrie 2015 16:22:03
Problema Diviz Scor 30
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.42 kb
#include <fstream>
#include <iostream>
#include <cstring>
#include <vector>
#include <array>
using namespace std;

constexpr int mod = 30103;

void do_firsts(const vector<char>& v, vector<array<int, 10>>& firsts, array<int, 10>& absolute_firsts){
	const int n = v.size();
	for(auto& x : firsts[n-1]){
		x = n; }
	for(int i = n-2; i >= 0; --i){
		firsts[i] = firsts[i+1];
		firsts[i][v[i+1]] = i+1; }
	absolute_firsts = firsts[0];
	absolute_firsts[v[0]] = 0; }

int main(){
	ifstream f("diviz.in");
	ofstream g("diviz.out");
	int k, a, b;
	f >> k >> a >> b >> ws;
	vector<char> v(201, 0);
	f.get(&v[0], 201, '\n');

	const int n = strlen(&v[0]);

	v.erase(begin(v) + n, end(v));
	v.shrink_to_fit();
	for(auto& x : v){
		x -= '0'; }

	vector<vector<vector<int>>> d(b+1, vector<vector<int>>(n, vector<int>(k, 0)));

	vector<array<int, 10>> firsts(n, array<int, 10>({}));
	array<int, 10> absolute_firsts;

	do_firsts(v, firsts, absolute_firsts);

	for(int i = 1; i < 10; ++i){
		if(absolute_firsts[i] < n){
			d[1][absolute_firsts[i]][i%k] = 1; } }
	for(int len = 1; len < b; ++len){
		for(int i = 0; i < n; ++i){
			for(int cifra = 0; cifra < 10; ++cifra){
				if(firsts[i][cifra] < n){
					for(int rest_k = 0; rest_k < k; ++rest_k){
						d[len+1][firsts[i][cifra]][(10*rest_k+cifra)%k] += d[len][i][rest_k]; } } } } }
	int rez = 0;
	for(int len = a; len <= b; ++len){
		for(int i = 0; i < n; ++i){
			rez += d[len][i][0]; } }
	g << rez;
	return 0; }