M比较好计算,N弄了半天时间.
首先对于front面的每一个高度front[i],在rightt面里面尽量先找相等的rightt[j],满足没有被其他相同高度front[k] (k != i)的匹配掉,如果找到了就填上front[i],如果没有相等的,找大于front[i]的最右边的rightt[j],然后填掉,如果依旧找不到,那么就留给rightt那边处理.
对于rightt做法相同.
#include <iostream>
#include <cstdio>
#include <memory.h>
#include <algorithm>
using namespace std;
const int maxn = 9;
int K;
int sq[maxn][maxn], front[maxn], rightt[maxn];
int used[maxn];
int main(){
int T;
scanf("%d", &T);
while(T--){
scanf("%d", &K);
memset(sq, 0, sizeof(sq));
memset(used, 0, sizeof(used));
for (int i = 0; i < K; ++i){
scanf("%d", &front[i]);
}
for (int i = 0; i < K; ++i){
scanf("%d", &rightt[i]);
}
int ansN = 0, ansM = 0;
for (int i = 0; i < K; ++i){
int idx = -1, ff = 0;
for (int j = 0; j < K; ++j){
if(rightt[j] == front[i]){
idx = j;
ff = 1;
if(!used[j]){
used[j] = 1;
idx = j;
break;
}
}else if(rightt[j] > front[i] && !ff){
idx = j;
}
}
if(idx != -1){
sq[i][idx] = front[i];
}
}
for (int i = 0; i < K; ++i){
int fl = 0;
for (int j = 0; j < K; ++j){
if(sq[j][i] == rightt[i]){
fl = 1;
break;
}
}
if(fl == 0){
int idx = -1, ff = 0;
for (int j = 0; j < K; ++j){
if(front[j] == rightt[i]){
idx = j;
ff = 1;
if(!used[j]){
used[j] = 1;
idx = j;
break;
}
}else if(front[j] > rightt[i] && !ff){
idx = j;
break;
}
}
if(idx != -1){
sq[idx][i] = rightt[i];
}
}
}
for (int i = 0; i < K; ++i){
for (int j = 0; j < K; ++j){
ansN += sq[i][j];
ansM += min(front[i], rightt[j]) - sq[i][j];
}
}
printf("Matty needs at least %d blocks, and can add at most %d extra blocks.\n", ansN, ansM);
}
return 0;
}