• PE51


    傳送門

    題意: 問最小的連續八個的素數家庭組 的最小素數, 其中素數家庭組 有部分重複數字 其他為遞增的數字

    類似如下格式

    56* *3

    56003
    56113
    56333
    56443
    56663
    56773
    56993

    然後真不會做, 看了這篇題解以後發現重複的數字必是 三個 才有可能出現八個素數(mathblog.dk/project-euler-51-eight-prime-family/)

    Result(mod 3)   模3的答案 Number of repeated digits 重複的數字數
      1 2 3 4 5
    0 4 4 10 4 4
    1 3 3 0 3 3
    2 3 3 0 3 3

      一個數是否能整除3  可以根據各個位上的數字之和 是否能整除3來判斷

     我們可以把符合條件的數字分成重複的和不重複的, 然後不重複的數字可以先不管  通過重複的數字和可以根據表格可以看出儅出現 一個重複數字的時候,
     比如說儅重複數字為 1個時,可能出現的情況是 0 1 2 3 4 5 6 7 8 9    有4個數(mod 3 = 0 )   有3個數(mod 3 = 1)    有3個數(mod 3 = 2)

     比如說儅重複數字為 2個時,可能出現的情況是 00 11 22  33 44 55 66 77 88 99    有4個數(mod 3 = 0 )   有3個數(mod 3 = 1)    有3個數(mod 3 = 2)

     比如說儅重複數字為 3個時,可能出現的情況是000 111 222  333 444 555 666 777 888 999 所有的情況都是 3*x  所以全部都是能整除的   有10個數(mod 3 = 0 )   有0個數(mod 3 = 1)    有0個數(mod 3 = 2)

     所以只有重複數字為 3個 時, 才有可能出現八個素數的情況  namo 假設答案是五位數 裏面選兩個數不重複 其他為重複的, 然後重複的數字需要從 0 1 2 開始才有可能有八個 且不能是結尾數字,
     所以就在前四位數字裏面選擇一位為 不重複數字 就有四種情況
     

      {1, 0, 0, 0, 1},
      {0, 1, 0, 0, 1},
      {0, 0, 1, 0, 1},
      {0, 0, 0, 1, 1}         1  代表非重複數字, 0 代表重複數字
    然後非重複數字用兩位數字填上, 重複數字由 0 1 2 開始枚舉是否符合素數條件

        答案是  六位數的話, 就在前面五位數字選兩個做非重複數字  於是有十種情況, 以此類推,

      {1, 1, 0, 0, 0, 1}, 
      {1, 0, 1, 0, 0, 1}, 
      {1, 0, 0, 1, 0, 1}, 
      {1, 0, 0, 0, 1, 1}, 
      {0, 1, 1, 0, 0, 1}, 
      {0, 1, 0, 1, 0, 1}, 
      {0, 1, 0, 0, 1, 1}, 
      {0, 0, 1, 1, 0, 1}, 
      {0, 0, 1, 0, 1, 1}, 
      {0, 0, 0, 1, 1, 1}

         跑一邊以後 發現 答案就是六位數

    #include <bits/stdc++.h> 
    
    using namespace std;
    using namespace std::chrono;
    
    #define _for(i,a,b)  for(int i = (a); i < (b); i++) 
    #define _rep(i,a,b)  for(int i = (a); i <= (b); i++)
    #define ll long long
    #define all(v) v.begin(), v.end()
    
    ll gcd(ll a, ll b) {return (!b)? a : gcd(b, a%b);}
    ll lcm(ll a, ll b) {return a/gcd(a, b)*b;}
    
    int is_prime(int x) {
      if(x < 2) return 0;
      int q = sqrt(x);
      _rep(i,2,q) if(x%i == 0) return 0;
      return 1;
    }
    
    int get5digitPatterns[4][5] = {
      {1, 0, 0, 0, 1},
      {0, 1, 0, 0, 1},
      {0, 0, 1, 0, 1},
      {0, 0, 0, 1, 1}
    };
    int get6digitPatterns[10][6] = {
      {1, 1, 0, 0, 0, 1}, 
      {1, 0, 1, 0, 0, 1}, 
      {1, 0, 0, 1, 0, 1}, 
      {1, 0, 0, 0, 1, 1}, 
      {0, 1, 1, 0, 0, 1}, 
      {0, 1, 0, 1, 0, 1}, 
      {0, 1, 0, 0, 1, 1}, 
      {0, 0, 1, 1, 0, 1}, 
      {0, 0, 1, 0, 1, 1}, 
      {0, 0, 0, 1, 1, 1}
    };
    int getLenOfArray(int *b) {return (sizeof(b)/sizeof(b[0]));}
    int fillPattern(int *b, int repeatingnumber,int n) {
      int res = 0;
      _for(i,0,n) {
        res *= 10;
        res += (b[i] == -1 ? repeatingnumber : b[i]); // 重複的數字填上, 其他照常
        //cout << "res = " << res << "
    ";
      } return res;
    }
    void pe51() {
      int a[10][10] = {}, row, col, n1;
      _for(i,11,1000) {// not repeating number
        if(i > 100) {
          _for(i,0,10) _for(j,0,6) a[i][j] = get6digitPatterns[i][j];
          row = 10, col = 6;
        }
        else {
          _for(i,0,4) _for(j,0,5) a[i][j] = get5digitPatterns[i][j];
          row = 4, col = 5;  
        }
        //_for(i1,0,row) {_for(j1,0,col) cout << a[i1][j1] << " "; cout << " ,a
    ";}
        _for(j,0,row) {
          int n = i;
          int b[10] = {};
          //_for(i1,0,col) cout << b[i1] << " "; cout << " , init b
    ";      cout << row << " = row
    ";
          for(int k = col-1; k >= 0; k--)  { // the starting repeating number(must 0 1 2 otherwise no possible 8 number family)
            if(a[j][k] == 1) b[k] = n%10, n /= 10; 
            else b[k] = -1;
          }
          //_for(i1,0,col) cout << b[i1] << " "; cout << " ,b
    ";
          //_for(i1,0,col) cout << a[j][i1] << " "; cout << " ,a
    ";
          _for(k,0,3) {
            if(k == 0 and b[0] == -1) continue; // first number is 0, skip
            int x = fillPattern(b, k, col);
            //_for(i1,0,10) cout << b[i1] << " ";         cout << " dsdsd, x= " << x << "
    "; 
            //return;
            if(is_prime(x)) {
              int cnt = 1;
              //cout << " , x= " << x << "
    "; 
              _for(repeatnumber, k+1, 10) if(is_prime(fillPattern(b, repeatnumber, col))) cnt++;
              if(cnt == 8) {
                cout << x << "
    ";
                _for(repeatnumber, k+1, 10) if(is_prime(fillPattern(b, repeatnumber, col))) cout << fillPattern(b, repeatnumber, col) << " "; cout << "
    ";
                //return;
              }
            }
          }
        }
      }
      return;
    }
    
    
    int main() {
        // ios::sync_with_stdio(false), cin.tie(nullptr);
        // taskA();
        // taskpe27();
        // taskA();
        cout << "start 
    ";
        auto start = high_resolution_clock::now();
        pe51();
        auto end = high_resolution_clock::now();
        auto duration = duration_cast<microseconds>(end - start);
        cout << "  cost = " << duration.count()/1000000 << "s
    ";
        cout << "end
    ";
        // pe27();
        return 0;
    }
    start 
    121313
    222323 323333 424343 525353 626363 828383 929393
      cost = 0s
    end
    Run result
  • 相关阅读:
    js全局变量和局部变量
    mysql分组后保留n条数据
    记一次微信公众号的开发与后台搭建
    Excel 导入 Sql Server出错——“文本被截断,或者一个或多个字符在目标代码页中没有匹配项”错误的解决
    一言之思-3
    时间获取
    sql基础的基础
    一言之思-2
    一言之思
    node.js日期
  • 原文地址:https://www.cnblogs.com/163467wyj/p/15164715.html
Copyright © 2020-2023  润新知