簡體   English   中英

找到三角形上或內部的點數,以獲得非常多的點數?

[英]Find the number of points on or inside a triangle for very large number of points?

在2D坐標系上給出N個格點(Xi,Yi),i = 1,2,...,N。 您必須處理Q查詢,每個查詢將以“xyd”形式給出。 令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,但在小測試用例上可以正常工作。 我哪里錯了?

檢查主函數的第一行:

int **X=(int **)malloc(300000*sizeof(int));

在這里,您動態分配二維數組X.現在,請參閱以下約束:

N ≤ 300000 (3 * 10^5)

所以,你的程序將分配X [3 * 10 ^ 5] [3 * 10 ^ 5]即。 9 * 10 ^ 10整數數組。 此大小的數組太大,無法容納在內存中。 在任何編程語言中,都不能分配/允許這樣大的存儲器。

請參閱以下鏈接

SIGSEGV是由無效的內存引用或分段錯誤引起的錯誤(信號)。 您可能正在嘗試訪問數組元素超出范圍或嘗試使用太多內存。

因此,由於內存過多,您的程序生成了SIGSEGV

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM