D. Gourmet choice(思维)

原题: http://codeforces.com/contest/1131/problem/D

题意:

有一个n长的数组a,m长的一个数组b,给出一个n*m矩阵x,x[i][j]表示a[i]和b[j]的关系(x[1][2]==’<’:a[1]<b[2])。让你反推ab数组使得两个数组中的最大值最小。

解析:

一开始就想到得出ab两个数组自己数组内部数的关系,但是想了好久怎么实现。后来发现只要和另外一个数组比较记录大的数的个数即可。

比方说,b数组中有5个比a[1]大,9个比a[2]大,那么a[1]>a[2]。这样得出两个数组的内部排名后,再类似归并排序那样,从小到大做一遍。

如果a[i]<b[j],那么接下来的一个数为a[i],再考虑a[i+1]是不是和a[i]相同(和b数组各个数对应的关系是否相同)。

最后是NO的问题,这个也简单,得出最后的答案后得出的关系是不是和给出矩阵一样判断。

#include<bits/stdc++.h>
using namespace std;
#define se second
#define fi first
typedef pair<int,int> pill;

int n,m;
char x[1011][1022];
int biga[1001],smla[1001],bigb[1001],smlb[1001];
// bigger than a[i]
bool cmpa(int i,int j){
    if(biga[i]!=biga[j])return biga[i]>biga[j];
    return smla[i]<smla[j];
}
bool cmpb(int i,int j){
    if(bigb[i]!=bigb[j])return bigb[i]>bigb[j];
    return smlb[i]<smlb[j];
}

bool check(int *a,int *b){
    for(int i=1;i<=n;i++){
        for(int j=1;j<=m;j++){
            if(x[i][j]=='<'&&!(a[i]<b[j]))return 1;

            if(x[i][j]=='='&&!(a[i]==b[j]))return 1;

            if(x[i][j]=='>'&&!(a[i]>b[j]))return 1;
        }
    }
    return 0;
}

int main(){
    cin>>n>>m;
    for(int i=1;i<=n;i++){
        scanf("%s",x[i]+1);
    }
    for(int i=1;i<=n;i++){
        for(int j=1;j<=m;j++){
            if(x[i][j]=='<'){
                biga[i]++;
                smlb[j]++;
            }
            else if(x[i][j]=='>'){
                bigb[j]++;
                smla[i]++;
            }
        }
    }
    int a[1001],b[1001];
    for(int i=1;i<=n;i++)a[i]=i;
    sort(a+1,a+1+n,cmpa);
    for(int j=1;j<=m;j++)b[j]=j;
    sort(b+1,b+1+m,cmpb);
    int ara=1,arb=1;
    int now=0;
    int ansa[1001],ansb[1001];
    while(ara<=n&&arb<=m){
        int A=a[ara],B=b[arb];
        if(x[A][B]!='<'){
            ansb[B]=now+1;
            arb++;
            while(arb<=m){
                if(bigb[b[arb]]==bigb[b[arb-1]]&&smlb[b[arb]]==smlb[b[arb-1]]){
                    ansb[b[arb]]=now+1;
                    arb++;
                    continue;
                }
                break;
            }
        }
        if(x[A][B]!='>'){
            ansa[A]=now+1;
            ara++;
            while(ara<=n){
                if(biga[a[ara]]==biga[a[ara-1]]&&smla[a[ara]]==smla[a[ara-1]]){
                    ansa[a[ara]]=now+1;
                    ara++;
                    continue;
                }
                break;
            }
        }
        now++;
    }
    while(ara<=n){
        ansa[a[ara]]=now+1;
        ara++;
        while(ara<=n){
            if(biga[a[ara]]==biga[a[ara-1]]&&smla[a[ara]]==smla[a[ara-1]]){
                ansa[a[ara]]=now+1;
                ara++;
                continue;
            }
            break;
        }
        now++;
    }
    while(arb<=m){
        ansb[b[arb]]=now+1;
        arb++;
        while(arb<=m){
            if(bigb[b[arb]]==bigb[b[arb-1]]&&smlb[b[arb]]==smlb[b[arb-1]]){
                ansb[b[arb]]=now+1;
                arb++;
                continue;
            }
            break;
        }
        now++;
    }

    if(!check(ansa,ansb)){
        printf("Yes\n");
        for(int i=1;i<=n;i++)printf("%d%c",ansa[i],(i==n?'\n':' '));
        for(int i=1;i<=m;i++)printf("%d%c",ansb[i],(i==m?'\n':' '));
    }
    else{
        printf("No\n");
    }
}

猜你喜欢

转载自blog.csdn.net/jk_chen_acmer/article/details/87902886