C. Skyscrapers (二维数组排序)

题目链接:https://codeforces.com/contest/1138/problem/C

题意:给出n*m的数字,然后在每个位置(i,j)上询问,此位置的行列中,有多少个数是大于此位置的值,多少个小于此位置的值,答案将它们加起来(包括本身)。

题解:我们对每一维排序,然后得到此位置的值是排第几的,那么就知道有多少个小于它,多少个大于它。

#include
#include
#include
#include

using namespace std;
const int N=1010;

int n,m,a[N][N],b[N];
///A表示此位置的行中,小于它的有多少个
///B表示此位置的列中,小于它的有多少个
///C表示此位置的行中,大于它的有多少个
///D表示此位置的列中,大于它的有多少个
int A[N][N],B[N][N],C[N][N],D[N][N];

map ma;

int main()
{
    scanf("%d%d",&n,&m);

    for(int i=1;i<=n;i++)
        for(int j=1;j<=m;j++)
        scanf("%d",&a[i][j]);

    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=m;j++)
            b[j]=a[i][j];

        sort(b+1,b+1+m);
        int t=unique(b+1,b+1+m)-b-1; ///剔除相等的值
//        printf("t=%d\n",t);
        ma.clear();
        for(int j=1;j<=t;j++)
            ma[b[j]]=j; ///标记此值在哪个位置

        for(int j=1;j<=m;j++){
            A[i][j]=ma[a[i][j]]-1;///行小
            C[i][j]=t-A[i][j]-1;///行大
//            printf("A[%d][%d]=%d,C[%d][%d]=%d\n",i,j,A[i][j],i,j,C[i][j]);
        }
    }

    for(int j=1;j<=m;j++)
    {
        for(int i=1;i<=n;i++)
            b[i]=a[i][j];

        sort(b+1,b+1+n);
        int t=unique(b+1,b+1+n)-b-1;
        ma.clear();
//        printf("t=%d\n",t);
        for(int i=1;i<=t;i++)
            ma[b[i]]=i;
        for(int i=1;i<=n;i++){
            B[i][j]=ma[a[i][j]]-1;///列小
            D[i][j]=t-B[i][j]-1;///列大
//            printf("B[%d][%d]=%d,D[%d][%d]=%d\n",i,j,B[i][j],i,j,D[i][j]);

        }
    }

    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=m;j++){
//                printf("%d %d %d %d\n",A[i][j],B[i][j],C[i][j],D[i][j]);
            printf("%d ",max(A[i][j],B[i][j])+max(C[i][j],D[i][j])+1);
        }
        puts("");
    }
    return 0;
}


































 

 

你可能感兴趣的:(cf)