USACO SuperPrime Rib
题目连接如下:http://ace.delos.com/usacoprob2?a=OhfCIAcGGcZ&S=sprime
这道题目是一道水题,本身不难,没什么算法思想,关键在于如何优化。如果说把输入的N位数字全部遍历来判断
是会超时的。我的想法如下:
- 第一个数字必须是质数,因为最后判断的时候就要求第一个数字是质数,这是题目要求
- 除第一个数字以外的其它数必须是奇数,因为如果是偶数的话,在cut的时候,以它为尾数的整数肯定能被
2整除就已经不是质数了
这里面在写代码的时候,我必须根据运行时的变量N来决定循环次数,因为我要手动去合成需要check的整数,
合成过程就是第一个数字外加N-1个奇数合成的整数,后来发现用递归来实现这个是最合适的,当时卡了一下。
如果这样优化是很接近pass的,但是还不够,我的最后一个优化就是在循环判断各个位组成的整数是否是质数的
时候反过来,先判断位数少的,如果是质数再判断位数多的,这个其实不是技巧,但至少也是一种优化,而且没想
到竟然pass了,这个挺神奇,
代码如下:
1: #include <iostream>
2: #include <cmath>
3: #include <fstream>
4: #include <vector>
5: #include <stack>
6:
7: using namespace std;
8:
9: vector<int> vec;
10:
11: //to show the function parameter
12: #define OUT
13: #define IN
14:
15: bool IsPrime(IN int nTest)
16: {
17: if(1 == nTest) //1 is not prime
18: return false;
19:
20: int nDivideTillNum = static_cast<int>(sqrt(static_cast<double>(nTest)));
21:
22: for(int i=2; i <= nDivideTillNum; i++)
23: {
24: if(nTest % i == 0)
25: {
26: return false;
27: }
28: }
29:
30: return true;
31: }
32:
33: bool IsSpecialPrime(IN int nTest, IN int nBitNum)
34: {
35: int nDivide=1;
36: stack<int> s;
37:
38: //to reversely check to speed the program
39: for(int i=0; i < nBitNum; i++)
40: {
41: s.push(nTest);
42: nTest = nTest / 10;
43: }
44: while( ! s.empty())
45: {
46: int nTemp = s.top();
47: s.pop();
48: if(! IsPrime(nTemp))
49: {
50: return false;
51: }
52: }
53:
54: return true;
55: }
56:
57: //
58: void GenerateNum(IN int n,IN int num)
59: {
60: if(0==n)
61: {
62: vec.push_back(num);
63: return;
64: }
65: int original_num = num;
66: for(int i=1; i <=9; i+=2)
67: {
68: num = num *10 + i;
69: GenerateNum(n-1,num);
70: num = original_num;
71: }
72: }
73:
74: int main(void)
75: {
76: ifstream ifs;
77: ifs.open("sprime.in");
78:
79: ofstream ofs;
80: ofs.open("sprime.out");
81:
82: int N=0;
83: ifs>>N;
84:
85: int nFirstNum[4] = {2,3,5,7};
86: int nTest=0;
87: GenerateNum(N-1,0);
88: for(int i=0; i < 4; i++)
89: {
90: nTest = nFirstNum[i] * pow(10.0,(double)(N-1));
91: for(vector<int>::iterator it=vec.begin(); it!=vec.end(); it++)
92: {
93: nTest += *it;
94: if(IsSpecialPrime(nTest,N))
95: {
96: ofs<<nTest<<endl;
97: }
98: nTest -= *it;
99: }
100: }
101:
102: ifs.close();
103: ofs.close();
104: return 0;
105: }