【题解】桐桐的猜想

题目描述

今天,桐桐在复习素数的知识时,发现了有趣的现象,例如4=2+2,5=2+3,6=3+3,7=2+5等等,桐桐列举了很多数,都是这样,所以她大胆地得出了一个结论:任何一个不小于4的数都能表示成两个质数的和。你能找出一些反例,证明桐桐的结论是错误的吗?

输入输出格式

输入格式

两行,第一行为一个整数n(1≤n≤50);接下来有n行,每行包含一个整数m。(3≤m≤106)(3≤m≤106)

输出格式

共n行,每行对应于每一个m,如果m不能表示成两个质数的和,则输出“NO WAY!”;否则输出一种方案。如果有多种可行方案,输出两个质数的差最大的那一种。

输入输出样例

输入样例

2

10

11

输出样例

10=3+7

NO WAY!

题解

一般人看到这题都是直接用筛法,事实上这个方法也可以。

#include <iostream>
#include <cstdio>
#include <cmath>

using namespace std;

int m, n[55], maxn;
int p[1000005];
int a[100005], cnt;

int main()
{
    scanf("%d", &m);
    for(register int i = 1; i <= m; ++i)
    {
        scanf("%d", n + i);
        if(n[i] > maxn) maxn = n[i];
    }
    for(register int i = 2; i <= maxn; ++i)
    {
        if(!p[i]) a[++cnt] = i;
        for(register int j = 1; i * a[j] <= maxn; ++j)
        {
            p[i * a[j]] = 1;
            if(!(i % a[j])) break;
        }
    }
    int op;
    for(register int i = 1; i <= m; ++i)
    {
        op = 0;
        for(register int j = 1; a[j] <= n[i] - a[j]; ++j)
        {
            if(!p[n[i] - a[j]])
            {
                printf("%d=%d+%d\n", n[i], a[j], n[i] - a[j]);
                op = 1;
                break;
            }
        }
        if(!op) printf("NO WAY!\n");
    }
    return 0;
}

参考程序1

但实际上这题,其实当m为偶数时间复杂度时是强哥德巴赫猜想,当m为奇数时,应该等于奇数加偶数,而偶数质数只有2,所以就能转换成当m为奇数时,判断m-2是否为质数

#include <iostream>
#include <cstdio>
#include <cmath>

using namespace std;

int m, n[55], maxn;
int p[1000005];
int a[100005], cnt;

int main()
{
    scanf("%d", &m);
    for(register int i = 1; i <= m; ++i)
    {
        scanf("%d", n + i);
        if(n[i] > maxn) maxn = n[i];
    }
    int srmaxn = sqrt(maxn);
    a[++cnt] = 2;
    for(register int i = 4; i <= maxn; i += 2)
    {
        p[i] = 1;
    }
    for(register int i = 3; i <= srmaxn; i += 2)
    {
        if(p[i]) continue;
        a[++cnt] = i;
        for(register int j = i + i; j <= maxn; j += i)
        {
            p[j] = 1;
        }
    }
    for(register int i = 1; i <= m; ++i)
    {
        if(n[i] & 1)
        {
            if(p[n[i] - 2]) printf("NO WAY!\n");
            else printf("%d=2+%d\n", n[i], n[i] - 2);
        }
        else
        {
            // 哥德巴赫猜想
            for(register int j = 1; ; ++j)
            {
                if(!p[n[i] - a[j]])
                {
                    printf("%d=%d+%d\n", n[i], a[j], n[i] - a[j]);
                    break;
                }
            }
        }
    }
    return 0;
}

参考程序2

到现在之后,其实这个程序还有优化的地方。

题目中给的n很小,我们可以把筛法缩减,然后后面暴力判断质数即可,这样就可以做到0ms了。所以合理分析时间复杂度还是很重要的。

#include <iostream>
#include <cstdio>
#include <cmath>

using namespace std;

int m, n[55], maxn;
int p[1000005];
int a[100005], cnt;

int main()
{
    scanf("%d", &m);
    for(register int i = 1; i <= m; ++i)
    {
        scanf("%d", n + i);
        if(n[i] > maxn) maxn = n[i];
    }
    int srmaxn = sqrt(maxn);
    a[++cnt] = 2;
    for(register int i = 4; i <= srmaxn; i += 2)
    {
        p[i] = 1;
    }
    for(register int i = 3; i <= srmaxn; i += 2)
    {
        if(p[i]) continue;
        a[++cnt] = i;
        for(register int j = i + i; j <= srmaxn; j += i)
        {
            p[j] = 1;
        }
    }
    int op;
    for(register int i = 1; i <= m; ++i)
    {
        if(n[i] & 1)
        {
            op = 0;
            for(register int j = 1; a[j] < n[i] - 2 && j <= cnt; ++j)
            {
                if((n[i] - 2) % a[j]) continue;
                printf("NO WAY!\n");
                op = 1;
                break;
            }
            if(!op) printf("%d=2+%d\n", n[i], n[i] - 2);
        }
        else
        {
            // 哥德巴赫猜想
            for(register int j = 1; a[j] <= n[i] - a[j]; ++j)
            {
                for(register int k = 1; a[k] < n[i] - a[j] && k <= cnt; ++k)
                {
                    if((n[i] - a[j]) % a[k]) continue;
                    goto NO_WAY;
                }
                printf("%d=%d+%d\n", n[i], a[j], n[i] - a[j]);
                break;
                NO_WAY:;
            }
        }
    }
    return 0;
}

参考程序3

原文地址:https://www.cnblogs.com/kcn999/p/10343501.html

时间: 2024-07-31 20:29:31

【题解】桐桐的猜想的相关文章

【题解】桐桐的爬山计划

题目描述 桐桐一直有个梦想,很希望像“蜘蛛人”罗伯特一样飞檐走壁.为了达成这个梦想,桐桐每天都辛勤练习攀爬.练习的出发点与终点都是在地上面.给出一个数列,代表她每次移动的距离.这个移动可以向上,也可以向下.但是不可能到达地下面去的.而她做练习使用的建筑物总是比她到达过的最高位置高2米.现在我们希望这个建筑物的高度越小越好. 如:20 20 20 20 如果是上,上,下,下的话,这个建筑物就要42米高,如果是上,下,上,下,就只要22米高. 当然有些数列是无解的,例如:3 4 2 1 6 4 5.

【题解】桐桐的递归函数

题目描述 桐桐经常找一些很有趣的数学书来阅读以增长自己的数学知识. 一天,他偶然发现一个递归函数w(a,b,c)有以下性质: 如果a≤0或b≤0或c≤0,就返回值1: 如果a>20或b>20或c>20,就返回w(20,20,20): 其它别的情况就返回w(a-1,b,c)+w(a-1,b-1,c)+w(a-1,b,c-1)-w(a-1,b-1,c-1). 桐桐想通过编程求出这个简单的递归函数的值,可是他在编程的时候遇到了一些困难.你能帮助他吗? 输入输出格式 输入格式: 一行,a,b,c

vijos1325 桐桐的糖果计划

Description 桐桐是一个快乐的小朋友,他生活中有许多许多好玩的事,让我们一起来看看吧-- 桐桐很喜欢吃棒棒糖.他家处在一大堆糖果店的附近. 但是,他们家的区域经常出现塞车.塞人等情况,这导致他不得不等到塞的车或人走光了他才能去买到他最爱吃的棒棒糖品种.于是,他去找市长帮他修路,使得每两个糖果店之间至少有两条完全不同的路.可是市长经费有限,于是让桐桐找出哪些路被塞住后会使某些糖果店与糖果店间无法到达及最少的修路条数.你能帮助他吃到他最喜爱的糖果吗? 注:1->3->2  和 1->

桐桐的糖果计划(vijos 1325)

背景 桐桐是一个快乐的小朋友,他生活中有许多许多好玩的事,让我们一起来看看吧…… 描述 桐桐很喜欢吃棒棒糖.他家处在一大堆糖果店的附近. 但是,他们家的区域经常出现塞车.塞人等情况,这导致他不得不等到塞的车或人走光了他才能去买到他最爱吃的棒棒糖品种.于是,他去找市长帮他修路,使得每两个糖果店之间至少有两条完全不同的路.可是市长经费有限,于是让桐桐找出哪些路被塞住后会使某些糖果店与糖果店间无法到达及最少的修路条数.你能帮助他吃到他最喜爱的糖果吗?注:1->3->2 和 1->3->4

偷懒的桐桐

偷懒的桐桐 题目描述 桐桐的老师布置桐桐写一个小根堆,但是桐桐不会堆的操作,所以想了一个偷懒的办法:堆是一棵完全二叉树,每个结点有一个权.小根堆的根的权最小,且根的两个子树也是一个堆.可以用一个数组a来记录一棵完全二叉树,a[1]为根结点,若结点a[j]不是根结点,那么它的父亲为a[j div 2]:若结点a[k]不是叶子结点,那么它的左儿子为a[2k],它的右儿子为a[2k+1]. 桐桐希望一组数据按一定顺序依次插入数组中(即第i个数为a[i]),最后得出来就已经是一个堆,即不需要任何交换操作

桐桐的贸易--WA

问题 A: 桐桐的贸易 时间限制: 1 Sec  内存限制: 64 MB提交: 15  解决: 2[提交][状态][讨论版] 题目描述 桐桐家在Allianceance城,好友ROBIN家在Horde城,假期,ROBIN邀桐桐去Horde城旅游.聪明的桐桐发现,A11iance城与Horde城的市场上的某些商品存在着很大的差价.可以从中获取相当可观的利润.为了赚回这次旅游的花费,桐桐决定在Alliance城购买一些商品,到Horde城以当地市场价卖掉,然后在Horde城买一些商品,再回到Alli

偷懒的桐桐(递归)

偷懒的桐桐 时间限制: 1 Sec  内存限制: 64 MB提交: 26  解决: 9[提交][状态][讨论版] 题目描述 桐桐的老师布置桐桐写一个小根堆,但是桐桐不会堆的操作,所以想了一个偷懒的办法:堆 是一棵完全二叉树,每个结点有一个权.小根堆的根的权最小,且根的两个子树也是一个堆.可以用一个数组a来记录一棵完全二叉树,a[1]为根结点,若结点 a[j]不是根结点,那么它的父亲为a[j div 2]:若结点a[k]不是叶子结点,那么它的左儿子为a[2k],它的右儿子为a[2k+1]. 桐桐希

桐桐的数学游戏(N皇后)

题目描述 相信大家都听过经典的“八皇后”问题吧?这个游戏要求在一个8×8的棋盘上放置8个皇后,使8个皇后互相不攻击(攻击的含义是有两个皇后在同一行或同一列或同一对角线上). 桐桐对这个游戏很感兴趣,也很快解决了这个问题.可是,他想为自己增加一点难度,于是他想求出n皇后的解的情况. 你能帮助她吗? 输入输出格式 输入格式: 一行,仅有一个数n(1≤n≤14),表示为n皇后问题. 输出格式: 输出仅有一个数,表示n皇后时问题的解法总数. 输入输出样例 输入样例: 8 输出样例: 92思路:从第一行开

Vijos P1325桐桐的糖果计划(有向图双连通分量)

/*重边不能删 不能删 不能删...*/ #include<iostream> #include<cstdio> #include<cstring> #define maxn 10010 using namespace std; int n,m,num,head[maxn],low[maxn],dfn[maxn],topt; int top,s[maxn],f[maxn],ans,sum,belong[maxn],r[maxn]; struct node{int v,p