簡體   English   中英

尋找一個有效的算法來回答給定方陣子矩陣中的查詢

[英]Finding an efficient algorithm to answer queries in a submatrix of a given square matrix

我正在嘗試解決2013年12月CodeChef競賽中“矩形查詢”問題

給定一個正方形矩陣N x N,其中填充了{1,.. 10}中的整數。 給定Q(10 ^ 5)查詢,如下所示:x1,y1,x2,y2查找給定子矩陣中唯一元素的數量。

限制:N <= 300 Q(10 ^ 5)x1 <= x2 <= N y1 <= y2 <= N時間限制1秒。

我嘗試過使用std :: set來實現唯一性的方法,但是獲得TLE ... MY方法太天真了。從左上角到右下角循環查詢,並添加元素以進行設置..然后打印std :: set.size ()。

有兩種可能的方法:

  1. 自行解決問題,並獲得來之不易的積分。

  2. 等待比賽結束並查看社論中的解決方案。

祝好運。

這是一個可以在時間限制內完成的簡單解決方案:-

#include<stdio.h>
#define max 300
int count[max][10][max];
int matrix[max][max];
int N;

void gen_counts() {
 int i,j,k,number,index;

 for(i=0;i<N;i++) {

    for(j=0;j<10;j++)
       count[i][j][0] = 0;
 }

 for(i=0;i<N;i++) {

   for(j=0;j<10;j++) {

    for(k=0;k<N;k++) {
        if(k>0)
           count[i][j][k] = count[i][j][k-1];

        if(matrix[i][k]==j+1) {
             count[i][j][k]++;
        }  

     }

   }

 }


}

int get_distinct(int r1,int c1,int r2,int c2) {
   int i,j,present[10],ret=0;
   for(i=0;i<10;i++)
      present[i] = 0; 
   for(i=r1;i<=r2;i++) {

     for(j=0;j<10;j++) {
        if(c1>0) 
        present[j]=present[j]||(count[i][j][c1-1]<count[i][j][c2]);
        else present[j] = present[j] || (count[i][j][c1]>0||count[i][j][c2]>0);
     }

   }
  for(i=0;i<10;i++)
     ret = ret + present[i];

  return(ret);
}



int main() {

int Q,i,j,r1,r2,c1,c2;

scanf("%d",&N);

for(i=0;i<N;i++) {

 for(j=0;j<N;j++)
   scanf("%d",&matrix[i][j]);
}

gen_counts();

scanf("%d",&Q);

for(i=0;i<Q;i++) {

 scanf("%d%d%d%d",&r1,&c1,&r2,&c2);
 printf("%d\n",get_distinct(r1-1,c1-1,r2-1,c2-1));

}


return(0);

}

我找到了解決該問題的最佳算法...我認為它的復雜度也小於O(n * n)。 我認為這將是有用的

#include <stdio.h>

int main(void) {
int n,i,j;
//read matrix dimensions
scanf("%d",&n);

int mat[n][n];
int t,x1,x2,y1,y2;
int counter[10],flag;
//read matrix
for(i=0;i<n;i++){
    for(j=0;j<n;j++){
        scanf("%d",&mat[i][j]);
    }
}

scanf("%d",&t);
//for each test case do this
while(t--){
    scanf("%d%d%d%d",&x1,&y1,&x2,&y2);

    //make all counters zero
    for(i = 0;i<10;i++){
        counter[i]=0;
    }

    flag = 0;

    for(i=x1-1;i<=x2-1;i++){
        for(j=y1-1;j<=y2-1;j++){
            //counter == 0 means we are visiting the element for the first time 
            counter[mat[i][j]-1]++;
        }

    }



    for(i =0;i<10 ;i++){
        if(counter[i]!=0){
            flag++;
        }
    }

    printf("%d\n",flag);

}
return 0;
}

暫無
暫無

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

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