EOJ3003. 最小向量点积

单点时限: 2.0 sec

内存限制: 256 MB

两个向量a=[a1,a2,⋯,an] 和b=[b1,b2,⋯,bn] 的点积定义为 :

例如,两个三维向量 [1,3,−5] 和 [4,−2,−1] 的点积是

假设允许对每个向量中的坐标值进行重新排列。找出所有排列中点积最小的一种排列,输出最小的那个点积值。

上例中的一种排列 [3,1,−5] 和 [−2,−1,4] 的点积为−27,这是最小的点积。

输入格式

第 1 行:一个整数 T (1⩽T⩽10) 为问题数。

接下来每个问题有 3 行。第 1 行是一个整数 n (1⩽n⩽1000),表示两个向量的维数。第2 行和第 3 行分别表示向量 a 和向量 b。每个向量都有 n 个由一个空格分隔的坐标值 坐标值(−1000⩽坐标值⩽1000) 组成。

输出格式

对于每个问题,输出一行问题的编号(0 开始编号,格式:case #0: 等)。

然后对应每个问题在一行中输出最小点积值。

样例

input

3
3
3 1 -5
-2 -1 4
1
2
-298
5
1 2 3 4 5
1 0 1 0 1

output

case #0:
-27
case #1:
-596
case #2:
6

解题思路

        假设维度是n,让A、B生成全排列然后暴力解的时间复杂度是O(n^2)。注意到最小点积可以是 “让vecA中最大的数 × vecB中最小的数” 从而简化运算。

        因此本例将vecA递增排序、vecB递减排序,最后求出每个job对应的点积 dotpdt 并输出。

示例代码

#include <iostream>
#include <bits/stdc++.h>
#include <math.h>
using namespace std;
class SingleJob{
public:
	int dim;
	vector<int> vecA; 
	vector<int> vecB;
};

int main() {
    int jobs, temp;
    SingleJob J[10];
    // 输入
    cin >> jobs;
	for(int i=0;i<jobs;i++){
		cin >> J[i].dim;
		for(int j=0;j<J[i].dim;j++){
			cin >> temp;
			J[i].vecA.insert(J[i].vecA.end(), temp);
		}
		for(int j=0;j<J[i].dim;j++){
			cin >> temp;
			J[i].vecB.insert(J[i].vecB.end(), temp);
		}
	}	
	// 输出
	int dotpdt=0;
	for(int i=0;i<jobs;i++){
		sort(J[i].vecA.begin() , J[i].vecA.end());
		sort(J[i].vecB.rbegin(), J[i].vecB.rend());
		cout << "case #" << i << ":" << endl;
		for(int j=0;j<J[i].dim;j++){
			dotpdt += J[i].vecA[j] * J[i].vecB[j];
		}	
		cout << sql << endl;
		dotpdt = 0;
	}
	return 0;
}   

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

谦谦青岫

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值