USACO 3.1 Humble Numbers

#include <stdio.h>
#define DEBUG 1
#define TESTCASES 9

#define MAX_PRIMES 100
#define MAX_N 100000
//注意别开小了
#define INF 0xFFFFFFFF

int numOfPrimes, Nth;
long long primeArray[MAX_PRIMES + 1];
long long humbleArray[MAX_N + 1];
//humbleIndex[primeIndex]表示第primeIndex个素数乘以第humbleIndex[primeIndex]个丑数刚好比当前发现的最大丑数humbleArray[numOfHumble]大
int humbleIndex[MAX_PRIMES + 1];

int main(){
#if DEBUG
	int testCase;
	for (testCase = 1; testCase <= TESTCASES; testCase++){
		char inputFileName[20] = "inputX.txt";
		inputFileName[5] = '1' +  (testCase - 1);
		freopen(inputFileName, "r", stdin);
		printf("\n#%d\n", testCase);
#endif
	
	scanf("%d%d", &numOfPrimes, &Nth);
	int primeIndex;
	for (primeIndex = 1; primeIndex <= numOfPrimes; primeIndex++){
		scanf("%d", &primeArray[primeIndex]);
		humbleIndex[primeIndex] = 0;
	}
	//每一个丑数都是由前面已经较小的丑数乘以某个素数求得,所以可以采用遍历素数再遍历丑数的方法计算,但因为丑数是有序的所以可以记录上次遍历到的丑数的位置
	/*
	for each prime p
		find the minimum humble number h
		  such that h * p is bigger than the last humble number.

	take the smallest h * p found: that's the next humble number.
	*/

	humbleArray[0] = 1;

	int n;
	long long minNextHumble;
	long long prime;
	int minPrimeIndex;
	for (n = 1; n <= Nth; n++){
		minNextHumble = INF;
		for (primeIndex = 1; primeIndex <= numOfPrimes; primeIndex++){
			prime = primeArray[primeIndex];
			while (humbleArray[ humbleIndex[primeIndex] ] * prime <= humbleArray[n - 1])
				humbleIndex[primeIndex]++;
			if (prime * humbleArray[ humbleIndex[primeIndex] ] < minNextHumble){
				minNextHumble = prime * humbleArray[ humbleIndex[primeIndex] ];
				minPrimeIndex = primeIndex;
			}
		}
		humbleArray[n] = minNextHumble;
		humbleIndex[minPrimeIndex]++;
	}

	printf("%d\n", humbleArray[Nth]);

#if DEBUG
	}
#endif
	return 0;
}



你可能感兴趣的:(USACO,3.1,Numbers,Humble)