2263: neighbor
时间限制: 1 Sec 内存限制: 256 MB提交: 205 解决: 56
[提交][状态][讨论版][命题人:admin]
题目描述
隔壁学校地形图可以通过一个高度矩阵表示,矩阵中每一个位置都有一个数hi ,
j表示这个坐标的海拔,我们姑且将其称为海拔图,容易发现,我们可以通过这个矩阵轻松算出隔壁学校的主视图,左视图。
相反的,我们却不能通过主视图和左视图唯一确定海拔图,现在问题来了,已知主视图左视图,我们需要知道铲平隔壁学校的代价上限和下限(即可能的体积最大值与最小值)
输入
第一行两个数 n , m (1 <=n ,m<=1000, 0<= hi ,j <= 1000), 分别表示海拔图的长和宽。
第二行 n 个数,描述了主视图每一个位置的高度。
第三行 m 个数,描述了左视图每一个位置的高度
输出
一行两个数,分别表示代价最小值与最大值。
样例输入
2 2 1 1 1 1
样例输出
2 4
#include <iostream> #include <cstring> using namespace std ; #define maxn 1100 int a[maxn] , b[maxn] ; int num[maxn][maxn] ; bool visit[maxn] ; int n , m ; int main(){ cin >> n >> m ; for(int i=1 ; i<=n ; i++){ cin >> a[i] ; } for(int i=1 ; i<=m ; i++){ cin >> b[i] ; } /*对应行列位置的最大值,是两个视图看过去的最小值, * 此行列位置的最小值是0 */ for(int i = 1 ; i <= n ; i ++ ) { for(int j = 1 ; j <= m ; j ++) { num[i][j] = min(a[i] , b[j]) ; } } int min_total = 0 ; for(int i = 1 ; i <= n ; i ++) { min_total += a[i] ; } for(int i = 1 ; i <= m ; i ++) { min_total += b[i] ; } memset(visit , false , sizeof(visit)) ; for(int i=1 ; i<=n ; i++){ for(int j=1 ; j<=m ; j++){ /*先将正视图和左视图高度相加,当体积取最小时每行每列只取一个小方块 * (每个符合条件的小方块被计算了两次) */ if(!visit[j]&&num[i][j] == a[i]&&b[j] == num[i][j] ){ visit[j] = true ; min_total -= a[i] ; break ; } } } cout<<min_total<<endl ; int max_total = 0 ; for(int i=1 ; i<= n ; i++){ for(int j=1 ; j<=m ; j++){ max_total += num[i][j] ; } } cout<<max_total<<endl ; return 0 ; }