[英]Algorithm, finding “number not divided by square numbers” between given min and max value
[英]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 ()。
有兩種可能的方法:
自行解決問題,並獲得來之不易的積分。
等待比賽結束並查看社論中的解決方案。
祝好運。
這是一個可以在時間限制內完成的簡單解決方案:-
#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.