我正在尝试解决“Rectangular Queries” problem from the December 2013 CodeChef contest:
给定方阵矩阵N x N,用{1,... 10}的整数填充。我们给出Q(10 ^ 5)个查询如下 给定x1,y1,x2,y2找到给定子矩阵中唯一元素的数量。
限制: N <= 300 问(10 ^ 5) x1&lt; = x2&lt; = N. y1&lt; = y2&lt; = N. 时限1秒
我尝试过使用std :: set获取唯一性的方法,但是获得了TLE ...我的方法很天真...从左上角到右下角循环查询并添加元素到set..then printing std :: set.size()。
答案 0 :(得分:7)
有两种可能的方法: -
自己解决问题并获得难以获得的积分。
等待比赛结束并在社论中查看解决方案。
答案 1 :(得分:1)
这是一个在时间限制内完成的简单解决方案: -
#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);
}
答案 2 :(得分: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;
}