【问题标题】:Prime generator program SPOJ wrong answerPrime生成器程序SPOJ错误答案
【发布时间】:2023-03-29 15:03:01
【问题描述】:

问题陈述

输入

输入以单行中的测试用例数量 t 开头 (t

输出

对于每个测试用例,打印所有质数 p,使得 m

示例

输入:

2
1 10
3 5

输出:

2
3
5
7

3
5

我的问题

我试图用golang 写这个问题,一开始我遇到时间限制超出错误,然后我通过找到最大的n 来解决它,并且只生成一次素数。但现在我得到了错误的答案错误。任何人都可以帮助找到错误?我想不通。谢谢。

package main

import (
    "fmt"
    "math"
)

func main() {
    var k, j, i, max_m, max_n, test_cases, kase int64
    fmt.Scanln(&test_cases)
    case_m, case_n := make([]int64, test_cases), make([]int64, test_cases)
    EratosthenesArray := make(map[int64][]bool)
    max_m = 0
    max_n = 0
    for i = 0; i < test_cases; i++ {
        fmt.Scanf("%d %d", &case_m[i], &case_n[i])
        if case_m[i] > case_n[i] {
            case_m[i] = 0
            case_n[i] = 0
        }
        if max_m < case_m[i] {
            max_m = case_m[i]
        }
        if max_n < case_n[i] {
            max_n = case_n[i]
        }
        length := case_n[i] - case_m[i] + 1
        EratosthenesArray[i] = make([]bool, length)
    }

    if max_m <= max_n {
        upperbound := int64(math.Sqrt(float64(max_n)))
        UpperboundArray := make([]bool, upperbound+1)
        for i = 2; i <= upperbound; i++ {
            if !UpperboundArray[i] {
                for k = i * i; k <= upperbound; k += i {
                    UpperboundArray[k] = true
                }
                for kase = 0; kase < test_cases; kase++ {
                    start := (case_m[kase] - i*i) / i

                    if case_m[kase]-i*i < 0 {
                        start = i
                    }
                    for k = start * i; k <= case_n[kase]; k += i {
                        if k >= case_m[kase] && k <= case_n[kase] {
                            EratosthenesArray[kase][k-case_m[kase]] = true
                        }
                    }
                }
            }
        }
    }

    for i = 0; i < test_cases; i++ {
        k = 0
        for j = 0; j < case_n[i]-case_m[i]; j++ {
            if !EratosthenesArray[i][j] {
                ret := case_m[i] + j
                if ret > 1 {
                    fmt.Println(ret)
                }
            }
        }
        fmt.Println()
    }
}

【问题讨论】:

  • 您是否尝试过独立运行它,比如在 ideone.com 上,使用您自己的输入并检查答案?
  • 你能解释一下你的方法吗?
  • @WillNess 确定我做到了,我测试了不同的数据范围,例如从 1 到 100、-100 到 -1、100 到 5000、10000 到 110000 等的素数,所有答案都是正确的。跨度>
  • @PhamTrung 根据问题,我们需要打印出给定范围内的素数,为了减少时间消耗和内存消耗,我使用了修改后的Sieve of Eratosthenes算法。首先,找到max_nmax_m,我们可以用它生成一个从1到sort(max_n)的Eratosthenes数组,然后我们可以推断出非质数到请求的范围。
  • 使用提供的示例输入运行您的代码并不会产生所需的输出,并且应该清楚地向您显示至少一个问题(3 5 测试用例仅给出 3 与您的代码)。

标签: algorithm go primes


【解决方案1】:

根据 cmets,每个素数范围的输出总是短一行,所以这里是 ACCEPTED 解决方案

package main

import (
    "fmt"
    "math"
)

func main() {
    var k, j, i, max_m, max_n, test_cases, kase int64
    fmt.Scanln(&test_cases)
    case_m, case_n := make([]int64, test_cases), make([]int64, test_cases)
    EratosthenesArray := make(map[int64][]bool)
    max_m = 0
    max_n = 0
    for i = 0; i < test_cases; i++ {
        fmt.Scanf("%d %d", &case_m[i], &case_n[i])
        if case_m[i] > case_n[i] {
            case_m[i] = 0
            case_n[i] = 0
        }
        if max_m < case_m[i] {
            max_m = case_m[i]
        }
        if max_n < case_n[i] {
            max_n = case_n[i]
        }
        length := case_n[i] - case_m[i] + 1
        EratosthenesArray[i] = make([]bool, length)
    }

    if max_m <= max_n {
        upperbound := int64(math.Sqrt(float64(max_n)))
        UpperboundArray := make([]bool, upperbound+1)
        for i = 2; i <= upperbound; i++ {
            if !UpperboundArray[i] {
                for k = i * i; k <= upperbound; k += i {
                    UpperboundArray[k] = true
                }
                for kase = 0; kase < test_cases; kase++ {
                    start := (case_m[kase] - i*i) / i

                    if case_m[kase]-i*i < 0 {
                        start = i
                    }
                    for k = start * i; k <= case_n[kase]; k += i {
                        if k >= case_m[kase] && k <= case_n[kase] {
                            EratosthenesArray[kase][k-case_m[kase]] = true
                        }
                    }
                }
            }
        }
    }

    for i = 0; i < test_cases; i++ {
        k = 0
        for j = 0; j <= case_n[i]-case_m[i]; j++ {
            if !EratosthenesArray[i][j] {
                ret := case_m[i] + j
                if ret > 1 {
                    fmt.Println(ret)
                }
            }
        }
        fmt.Println()
    }
}

请注意,我只将一行从for j = 0; j &lt; case_n[i]-case_m[i]; j++ { 更改为for j = 0; j &lt;= case_n[i]-case_m[i]; j++ {

并且执行时间大约是1.08s,内存大约是772M(但是好像spoj中golang的初始内存是771M,所以可能是1M左右的内存使用)

【讨论】:

    猜你喜欢
    • 2018-02-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-11-21
    • 1970-01-01
    相关资源
    最近更新 更多