Cod sursa(job #232232)

Utilizator mist000000 mist Data 14 decembrie 2008 22:20:19
Problema A+B Scor 0
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.82 kb
#include <iostream>
#include <fstream>
#include <cmath>

using namespace std;

bool isPrime(int x)
{
	if (x < 2)
		return false;
	if (x == 2)
		return true;
	if (x % 2 == 0)
		return false;

	int limit = sqrt(x);
	for (int i = 3; i <= limit; i+=2) {
		if (x % i == 0)
			return false;
	}
	return true;
}

long findPrimePos(int *v, long size, long startIndex)
{
	while (startIndex < size &&  !isPrime(v[startIndex]))
			startIndex++;
	return startIndex;
}

void outputSol(long long sol)
{
	ofstream out("kprime.out");
	out << sol << endl;
	out.close();
}

int main()
{
	ifstream in("kprime.in");
	long n, k;
	in >> n;
	in >> k;
	int *v = new int[n];
	for (long i = 0; i < n; i++)
		in >> v[i];
	in.close();

	if (k <= 0) {
		outputSol(0);
		return 0;
	}

	long *jmp = new long[n];
	long leftPrime = findPrimePos(v, n, 0);
	if (leftPrime == n) {
		// no prime numbers in input
		outputSol(0);
		return 0;
	}

	// find all primes and mark intervals in jmp[] vector
	long crt = leftPrime;
	while (crt < n) {
		long next = findPrimePos(v, n, crt + 1);
		jmp[crt] = next - crt;
		crt = next;
	}

	// non-primes to the left + 1
	long leftCount = leftPrime + 1;
	long rightPrime = leftPrime;
	// non-primes to the right + 1
	long rightCount = jmp[rightPrime];
	// primes in interval [left, right]
	long primesInSeq = 1;

	// put k prime numbers between [left, right]
	while (primesInSeq < k && rightPrime < n) {
		rightPrime += jmp[rightPrime];
		rightCount = jmp[rightPrime];
		primesInSeq++;
	}

	if (primesInSeq < k || rightPrime == n) {
		// less than k primes in sequence
		outputSol(0);
		return 0;
	}

	long long solutions = 0;

	while (rightPrime < n) {
		solutions += leftCount * rightCount;

		leftCount = jmp[leftPrime];
		leftPrime += jmp[leftPrime];

		rightPrime += jmp[rightPrime];
		rightCount = jmp[rightPrime];
	}

	outputSol(solutions);

	return 0;
}