zoukankan      html  css  js  c++  java
  • 多种方法过Codeforces Round #270的A题(奇偶法、打表法和Miller_Rabin(这个方法才是重点))

    题目链接:http://codeforces.com/contest/472/problem/A

    题目:

    题意:哥德巴赫猜想是:一个大于2的素数一定可以表示为两个素数的和。此题则是将其修改为:一个大于等于12的数一定能表示为两个合数的和。

    思路:这个很容易,下面是三种方法的代码。

    奇偶法:一个数要么是奇数要么是偶数,众所周知大于2的偶数都是合数(因为都能被2整除嘛),所以只要把该数分解为两个非2的偶数的和即可。

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 #define ll long long 
     4 #define pb push_back
     5 #define mem(a,b) memset(a,b,sizeof(a))
     6 
     7 int main()
     8 {
     9     ios::sync_with_stdio(false);
    10     cin.tie(0);
    11     int n;
    12     cin>>n;
    13     if(n%2==0)cout<<4<<' '<<n-4<<endl;
    14     else cout<<9<<' '<<n-9<<endl;
    15     return 0;    
    16 } 

    打表法:将素数筛出来,然后进行遍历即可。

     1 #include <iostream>
     2 using namespace std;
     3 
     4 const int maxn = 1e6 + 7;
     5 int n;
     6 int p[maxn];
     7 
     8 void init() {
     9     for(int i = 2; i < maxn; i++) {
    10         p[i] = 1;
    11     }
    12     for(int i = 2; i * i < maxn; i++) {
    13         if(p[i]) {
    14             for(int j = i * i; j < maxn; j += i) {
    15                 p[j] = 0;
    16             }
    17         }
    18     }
    19 }
    20 
    21 int main() {
    22     init();
    23     cin >>n;
    24     for(int i = n / 2; i >= 1; i--) {
    25         if(!p[i] && !p[n - i]) {
    26             cout <<i <<" " <<n - i <<endl;
    27             return 0;
    28         }
    29     }
    30     return 0;
    31 }

    Miller_Rabin法:这个是关键,其实这种方法的思路和上一种方法一样,不过不是打表,而是用Miller_Rabin来判断是否为素数,最重要的是Miller_Rabin法可以判断大素数,而打表却不可以!!!(计蒜客上一题也是用这个方法,且是大数据,打表不可过,链接为:https://nanti.jisuanke.com/t/25985,这个题的题解链接为https://www.cnblogs.com/Dillonh/p/9301991.html).

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 
     4 typedef long long ll;
     5 int n;
     6 
     7 ll multi(ll a, ll b, ll mod) {
     8     ll ret = 0;
     9     while(b) {
    10         if(b & 1)
    11             ret = ret + a;
    12         if(ret >= mod)
    13             ret -= mod;
    14 
    15         a = a + a;
    16         if(a >= mod)
    17             a -= mod;
    18         b >>= 1;
    19     }
    20     return ret;
    21 }
    22 ll quick_pow(ll a, ll b, ll mod) {
    23     ll ret = 1;
    24     while(b) {
    25         if(b & 1)
    26             ret = multi(ret, a, mod);
    27         a = multi(a, a, mod);
    28         b >>= 1;
    29     }
    30     return ret;
    31 }
    32 bool Miller_Rabin(ll n) {
    33     ll u = n - 1, pre, x;
    34     int i, j, k = 0;
    35     if(n == 2 || n == 3 || n == 5 || n == 7 || n  == 11)
    36         return true;
    37     if(n == 1 || (!(n % 2)) || (!(n % 3)) || (!(n % 5)) || (!(n % 7)) || (!(n % 11)))
    38         return false;
    39     for(; !(u & 1); k++, u >>= 1);
    40     srand(time(NULL));
    41     for(i = 0; i < 5; i++) {
    42         x = rand() % (n - 2) + 2;
    43         x = quick_pow(x, u, n);
    44         pre = x;
    45         for(j = 0; j < k; j++) {
    46             x = multi(x, x, n);
    47             if(x == 1 && pre != 1 && pre != (n - 1))
    48                 return false;
    49             pre = x;
    50         }
    51         if(x != 1)
    52             return false;
    53     }
    54     return true;
    55 }
    56 
    57 
    58 int main() {
    59     cin >>n;
    60     for(int i = n / 2; i >= 1; i--) {
    61         if(!Miller_Rabin(i) && !Miller_Rabin(n - i)) {
    62             cout <<i <<" " <<n - i <<endl;
    63             return 0;
    64         }
    65     }
    66     return 0;
    67 }
  • 相关阅读:
    理解volatile与synchronized
    实现任意两个数的互换
    增删改查+部分前段内容
    Hibernate知识点小结汇总
    Spring知识点小结(一)
    JDBC相关
    Redis工具之Jedis
    Hibernate知识点小结(四)--JPA
    Hibernate知识点小结(三)-->一对多与多对多配置
    Hibernate知识点小结(二)
  • 原文地址:https://www.cnblogs.com/Dillonh/p/9301972.html
Copyright © 2011-2022 走看看