USACO4.3.2——质数方阵暴力解法

USACO4.3.2——质数方阵暴力解法

题面链接:这里

读过题后,就不难发现这是一道填数题,先说填法,大多数人一开始肯定想到一行行填,一列列填,填完后整体判断——大数据直接把你T废:
在这里插入图片描述

于是我们就开始关注一些已经确定的点,确定的点越多,可供选择的素数就越少,运行速度就越快,请看下图:

在这里插入图片描述

图中的深红色(最左上角)表示题目中确定的点,我们先填第一行第一列(红色),这样有一个约束条件(一头确定),再填右上-左下的那条斜边(紫色),这样有两个约束条件(一头一尾已经确定),再填左上-右下的那条斜边(深蓝),再填浅蓝和绿色,它们都有两个约束条件。最后算出橙色的值,用总值减去其他四个数的值,如果是负数或大于10,就退回来重新做。

整体做完后,按照题目所给的条件进行判断,不符合就退回来重新做。

输出答案前需要先排序,将答案二维数组存到一个字符串中,这样就可以方便比较。

这里需要重点提的一点便是判质,下面是我刚开始写的一段代码:

bool Judge_Num(int Num) {
    for (register int i = 2; i <= sqrt(Num); i++)
        if (Num % i == 0)
            return false;
    // cout<<Num<<endl;
    return true;
}

注意,它会爆——每次循环计算一次sqrt是很耗时间的,所以,我做了以下改进:

bool Judge_Num(int Num) {
	int T=sqrt(Num);//这样只要计算一次sqrt
    for (register int i = 2; i <= T; i++)
        if (Num % i == 0)
            return false;
    // cout<<Num<<endl;
    return true;
}

可是还是会超时(Num是一个五位数,每次循环少说也要100次),能不能将判质时间缩到O(1)呢?
可以的:
我们在填数之前先用欧拉筛将10000到99999中的素数筛出来,用bool数组Visited储存,Visited[N]=1表示N是质数,Visited[N]=0表示N是不是质数,这样,每次判质时,我们只需要:

bool Judge_Num(int Num){
	return true-Visited[Num];
}

万事大吉

代码(号称USACO史上最长):

#include "bits/stdc++.h"
using namespace std;

struct Unsigned {
    int Size, Num[1001];
    int E[1001][11];
} Prime[11];//储存每一个素数
int Sum, Start, Used[9], Result[9][9], Size, prime[100100];
bool Can, Visited[100101];
const int N = 5, M = 9;

struct Out {
    string Name;
    int Num_Result[9][9];
    friend bool operator<(Out Num1, Out Num2) { ret
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值