在2D坐标系上给出N个格点(Xi,Yi),i = 1,2,...,N。 您必须处理Q查询,每个查询将以“x y d”的形式给出。 令ABC为具有顶点A(x + d,y),B(x,y)和C(x,y + d)的三角形。 对于每个查询,您必须找到有多少给定格点位于三角形ABC的边界内或边界上。 输入
输入的第一行包含两个空格分隔的整数N和Q. 以下N行中的每一行具有两个空间有效的整数Xi,Yi给出格点的x和y坐标。 然后,以下Q行包含三个空格分隔的整数x,y,d给出查询。 输出
对于每个查询,在一行上输出一个整数,该整数表示位于三角形内部或边界上的给定晶格点的数量。 约束
1≤N≤300000(3 * 105)
1≤Q≤200000(2 * 105)
1≤Xi,Yi≤300000(3 * 105)
1≤x,y,d≤300000(3 * 105)
样品
Input 1:
5 3
1 3
1 5
3 6
4 4
2 6
1 5 3
1 5 4
1 1 1
Output 1:
3
3
0
Input 2:
2 2
1 5
3 7
2 5 6
2 3 4
Output 2:
1
0
#include<iostream>
#include<cstdio>
#include<cstdlib>
using namespace std;
int sizer[300000]={0};//sizer[i] tells the number of points having i as the abscissa
int cmp(const void *a,const void *b)
{
return *(int *)a-*(int *)b;
}
int main()
{
int **X=(int **)malloc(300000*sizeof(int));//each pointer points to an array of ints
for(int i=0;i<300000;i++)
X[i]=NULL;
int N,Q;
int x,y,d;
scanf("%d %d",&N,&Q);
scanf("%d %d",&x,&y);
sizer[x-1]++;
for(int i=1;i<=N;i++)
{
scanf("%d %d",&x,&y);
sizer[x-1]++;
X[x-1]=(int *)realloc(X[x-1],sizer[x-1]*sizeof(int));
X[x-1][sizer[x-1]-1]=y;}
for(int i=0;i<300000;i++)
{
if(X[i]!=NULL)
qsort(X[i],sizer[i],sizeof(int),cmp);}//sorts all the ordinates
for(int i=1;i<=Q;i++)//query loop
{
scanf("%d %d %d",&x,&y,&d);
int count=0;
for(int j=x;j<=x+d;j++)//this loop works for each row from x to x+d
{
if(X[j-1]==NULL)//no points on X=j line
continue;
else if(X[j-1][sizer[j-1]-1]<y)//the largest ordinate point on X=j line is <y ie below the triangle
continue;
else if(X[j-1][0]+j>x+y+d)//the smallest ordinate point on X=j line is above the triangle
continue;
int k=0;
for(;X[j-1][k]<y&&k<sizer[j-1];k++);//k is the position from where counting of points begins.moving along the X=j line and counting the points
int v=k;
for(;X[j-1][v]+j<=x+y+d&&v<sizer[j-1];v++);
count=count+v-k;}
printf("%d\n",count);}
return 0;}
当输入案例非常大时,我在网上判断时得到一个SIGSEGV 但在小型测试用例上可以正常工作。 我哪里错了?
答案 0 :(得分:2)
检查主函数的第一行:
int **X=(int **)malloc(300000*sizeof(int));
这里,你动态分配一个二维数组X. 现在,请参阅以下约束:
N ≤ 300000 (3 * 10^5)
所以,你的程序将分配X [3 * 10 ^ 5] [3 * 10 ^ 5]即。 9 * 10 ^ 10整数数组。 此大小的数组太大,无法容纳在内存中。 在任何编程语言中,都不能分配/允许这么大的内存。
请参阅以下Link
SIGSEGV是由无效的内存引用或分段错误引起的错误(信号)。您可能正在尝试访问数组元素超出范围或尝试使用太多内存。
因此,由于内存过多,您的程序会生成 SIGSEGV 。