素数生成器程序 SPOJ 错误答案

huangapple go评论88阅读模式
英文:

Prime generator program SPOJ wrong answer

问题

问题描述

> 输入
>
> 输入以单行中的测试用例数 t 开始(t<=10)。在接下来的 t 行中,有两个数字 m 和 n(1 <= m <= n <= 1000000000,n-m<=100000),用空格分隔。
>
> 输出
>
> 对于每个测试用例,打印所有满足 m <= p <= n 的素数 p,每行一个数字,用空行分隔测试用例。
>
> 示例
>
> 输入:
>
> 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()
    }
}
英文:

Problem Statement

> Input
>
> The input begins with the number t of test cases in a single line
> (t<=10). In each of the next t lines there are two numbers m and n (1
> <= m <= n <= 1000000000, n-m<=100000) separated by a space.
>
> Output
>
> For every test case print all prime numbers p such that m <= p <= n,
> one number per line, test cases separated by an empty line.
>
> Example
>
> Input:
>
> 2
> 1 10
> 3 5
>
> Output:
>
> 2
> 3
> 5
> 7
>
> 3
> 5

My Problem

I have tried to write this problem with golang, at beginning I got time limit exceed error, then I solved it with finding the biggest n and only generate prime once. But now I got wrong answer error. Anyone can help to to find the bug? I can't figure it out. Thanks.

package main
import (
&quot;fmt&quot;
&quot;math&quot;
)
func main() {
var k, j, i, max_m, max_n, test_cases, kase int64
fmt.Scanln(&amp;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 &lt; test_cases; i++ {
fmt.Scanf(&quot;%d %d&quot;, &amp;case_m[i], &amp;case_n[i])
if case_m[i] &gt; case_n[i] {
case_m[i] = 0
case_n[i] = 0
}
if max_m &lt; case_m[i] {
max_m = case_m[i]
}
if max_n &lt; case_n[i] {
max_n = case_n[i]
}
length := case_n[i] - case_m[i] + 1
EratosthenesArray[i] = make([]bool, length)
}
if max_m &lt;= max_n {
upperbound := int64(math.Sqrt(float64(max_n)))
UpperboundArray := make([]bool, upperbound+1)
for i = 2; i &lt;= upperbound; i++ {
if !UpperboundArray[i] {
for k = i * i; k &lt;= upperbound; k += i {
UpperboundArray[k] = true
}
for kase = 0; kase &lt; test_cases; kase++ {
start := (case_m[kase] - i*i) / i
if case_m[kase]-i*i &lt; 0 {
start = i
}
for k = start * i; k &lt;= case_n[kase]; k += i {
if k &gt;= case_m[kase] &amp;&amp; k &lt;= case_n[kase] {
EratosthenesArray[kase][k-case_m[kase]] = true
}
}
}
}
}
}
for i = 0; i &lt; test_cases; i++ {
k = 0
for j = 0; j &lt; case_n[i]-case_m[i]; j++ {
if !EratosthenesArray[i][j] {
ret := case_m[i] + j
if ret &gt; 1 {
fmt.Println(ret)
}
}
}
fmt.Println()
}
}

答案1

得分: 1

根据评论,每个质数范围的输出总是少一行,所以这是一个被接受的解决方案。

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 < case_n[i]-case_m[i]; j++ { 改为 for j = 0; j <= case_n[i]-case_m[i]; j++ {

执行时间约为1.08秒,内存约为772M(但似乎golang在spoj中的初始内存为771M,所以实际内存使用可能为1M)。

英文:

according to the comments, the output for each prime number range is always have one line short, so here is the ACCEPTED solution

package main
import (
&quot;fmt&quot;
&quot;math&quot;
)
func main() {
var k, j, i, max_m, max_n, test_cases, kase int64
fmt.Scanln(&amp;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 &lt; test_cases; i++ {
fmt.Scanf(&quot;%d %d&quot;, &amp;case_m[i], &amp;case_n[i])
if case_m[i] &gt; case_n[i] {
case_m[i] = 0
case_n[i] = 0
}
if max_m &lt; case_m[i] {
max_m = case_m[i]
}
if max_n &lt; case_n[i] {
max_n = case_n[i]
}
length := case_n[i] - case_m[i] + 1
EratosthenesArray[i] = make([]bool, length)
}
if max_m &lt;= max_n {
upperbound := int64(math.Sqrt(float64(max_n)))
UpperboundArray := make([]bool, upperbound+1)
for i = 2; i &lt;= upperbound; i++ {
if !UpperboundArray[i] {
for k = i * i; k &lt;= upperbound; k += i {
UpperboundArray[k] = true
}
for kase = 0; kase &lt; test_cases; kase++ {
start := (case_m[kase] - i*i) / i
if case_m[kase]-i*i &lt; 0 {
start = i
}
for k = start * i; k &lt;= case_n[kase]; k += i {
if k &gt;= case_m[kase] &amp;&amp; k &lt;= case_n[kase] {
EratosthenesArray[kase][k-case_m[kase]] = true
}
}
}
}
}
}
for i = 0; i &lt; test_cases; i++ {
k = 0
for j = 0; j &lt;= case_n[i]-case_m[i]; j++ {
if !EratosthenesArray[i][j] {
ret := case_m[i] + j
if ret &gt; 1 {
fmt.Println(ret)
}
}
}
fmt.Println()
}
}

Note that I only changed one line from for j = 0; j &lt; case_n[i]-case_m[i]; j++ { to for j = 0; j &lt;= case_n[i]-case_m[i]; j++ {

And the execution time is about 1.08s, memory is about 772M (but seems the initial memory for golang in spoj is 771M, so it might be about 1M memory usage)

huangapple
  • 本文由 发表于 2015年7月19日 15:39:01
  • 转载请务必保留本文链接:https://go.coder-hub.com/31499007.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定