【发布时间】:2015-01-14 13:56:38
【问题描述】:
该程序使用限制 (low,up) 在 int 数组 (Kseek) 中进行二进制搜索。请忽略一些看起来很奇怪的指令,我还没有完成所有必须做的事情。
奇怪的是,我的代码在我的大学评分器中完美运行,但在我的电脑中的大型测试用例出现了段错误。我不明白错误在哪里,对于具有 N>4000 个元素的输入,它会崩溃。
我没有使用任何指针或任何内存分配,我认为 scanf 可能会出现段错误并尝试更改某些属性但它仍然崩溃。
gcc 是否有可能在编译过程中有“内存分配边界”,然后当我尝试运行程序时它无法分配我需要的内存大小??
如果你有时间请检查我的代码,可能有一个我无法发现的错误。
提前致谢!
#include <stdio.h>
int main()
{
int N, K, up, low, pos, flag=1 ;
scanf("%d %d\n", &N, &K);
int s[N], f[N], i=0;
while( scanf("%d %d\n", &s[i], &f[i]) != EOF) { i++; }
i=0;
up=f[0];
low=s[0];
while(i < N )
{
if ( f[i] > up) up=f[i];
if ( s[i] < low) low=s[i];
i++;
}
int Kseek[up];
i=0;
while( flag )
{
pos = ( low + up ) / 2;
i=0;
Kseek[pos]=0;
while ( i < N)
{
if ( pos >= f[i] )
{
Kseek[pos]=f[i]-s[i]+1+Kseek[pos];
}
else if ( pos >= s[i] && pos <f[i])
{
Kseek[pos]=pos-s[i]+1+Kseek[pos];
}
i++;
}
if ( Kseek[pos] == K ) flag=0;
else if ( Kseek[pos] > K )
{
i=0;
Kseek[pos-1]=0;
while ( i < N)
{
if ( (pos-1) >= f[i] )
{
Kseek[pos-1]=f[i]-s[i]+1+Kseek[pos-1];
}
else if ( (pos-1) >= s[i] && (pos-1) <f[i])
{
Kseek[pos-1]=(pos-1)-s[i]+1+Kseek[pos-1];
}
i++;
}
if ( Kseek[pos] > K && Kseek[pos-1] < K) flag=0;
else if ( Kseek[pos-1] == K ) { pos-=1; flag=0; }
up = pos - 1;
}
else if ( Kseek[pos] < K)
{
i=0;
Kseek[pos+1]=0;
while ( i < N)
{
if ( (pos+1) >= f[i] )
{
Kseek[pos+1]=f[i]-s[i]+1+Kseek[pos+1];
}
else if ( (pos+1) >= s[i] && (pos+1) <f[i])
{
Kseek[pos+1]=(pos+1)-s[i]+1+Kseek[pos+1];
}
i++;
}
if ( (Kseek[pos+1] > K && Kseek[pos] < K) || Kseek[pos+1] == K) { flag=0; pos+=1; }
low = pos + 1;
}
}
printf("%d\n", pos);
return 0;
}
输入文件看起来总是这样。条目从 10 到 50000 不等:
200 50536
369 732
595 644
460 500
548 975
270 546
662 766
358 767
719 929
284 354
411 949
169 210
488 679
103 462
180 188
364 487
407 477
234 586
23 775
504 698
79 906
......
...
第一行总是 K 和 N,接下来是 s[i], f[i] 用于接下来的 N 行。
【问题讨论】:
-
我正在使用 gcc。它编译良好,没有警告。
-
哦,我明白了,这不是 C90 标准功能。
-
我很难理解这个二分搜索在搜索什么?
-
它正在搜索数字 K。K == Kseek[pos] 或者 Kseek[pos] > K > Kseek[pos+1]。这个练习叫做巧克力工厂,嗯,在一个工厂里有N个巧克力来源和一个大罐子。您正在寻找罐中正好有 K 升巧克力的那一刻。每个源在时间 si 开始倒巧克力,在时间 fi 停止(均为整数)。我的目标是快速找到那个时间(pos),所以我写的算法是使用复杂度为Θ(nlogn)的二进制搜索。边界是一个源开始倾倒(低)的第一个时刻和最后一个
-
@Anonymous VLA(可变长度数组)功能自 90 年代初就作为扩展提供,并在 c99 中标准化并在 c11 中扩展。
标签: c segmentation-fault