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:  }
原文地址:https://www.cnblogs.com/HappyAngel/p/2119713.html