原题: 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");
}
}