CCF CSP 2020-06-2 “稀疏向量” 解题思路及满分代码(C++11)

2023-05-16

文章目录

    • 题目描述
    • 解题思路
    • 满分代码

题目描述

在这里插入图片描述
在这里插入图片描述

解题思路

题目的要求其实就是一个计算向量点乘的问题,只是题中给出的“稀疏向量”中有很多0,我们要做的就是根据给出的非零值,直接计算出两个向量的内积。

从题目给出的定义来看,index和value是一一对应的键值对,可以用STL的map来实现,也可以自定义结构体用数组来存储,这里我用结构体来实现:

typedef struct nzero {
	int index;
	int value;
}nzero;

下面我们根据样例来分析解题步骤:
在这里插入图片描述
由于两个向量除了给出维度的值,其余维度都为0,所以我们在计算内积时,只有两个向量在同一维度上都不为0才需要进行计算。由上图样例1所示,u和v两个数组中,只有存在相同index值的value才能参与计算。

于是我们的解题关键就在于找出u和v两个数组中具有相同index的项。

这是一个简单问题,用嵌套for循环就可以实现,对于u中每一项的index,遍历v,寻找相同的index即可。但是题中给出的a,b(u,v数组的规模)最大可达到 5 × 1 0 5 5×10^5 5×105如果对u中每一项都遍历v来判断,时间复杂度最大就会超过 O ( 1 0 10 ) O(10^{10}) O(1010),必然会导致超时。

所以我们对内层循环应该进行优化,看看能否减少循环次数。

根据样例1,我们会发现u和v在输入时是按照index升序排列的,其实就是一个向量的值是按维度从小到大来写的。而我们在推导遍历样例时会发现,其实对于u中的每一个index,并不需要对v从头到尾遍历,接着上一次的继续往下寻找就可以完成要求。于是我们可以对v数组引入一个指针(只是类似指针一样指向下标,并不需要真的指针),在遍历u的过程中同时对v遍历,最终两个数组都只需要遍历一遍,这样一来时间复杂度最大就只有 O ( 1 0 6 ) O(10^6) O(106),就不会超时了。

但是题中只给出了一个样例,我们并不能保证其他测试样例在输入值就会按index值升序排列,因此我们在输入完之后需要先对u和v进行排序:

bool cmp(nzero a, nzero b) {
	return a.index < b.index;
}
	sort(u, u+a, cmp);
	sort(v, v+b, cmp);

注:由于每个value绝对值最大可达到 1 0 6 10^6 106,因此最终的结果应定义成long long类型,不然会导致结果错误。

完整满分代码贴在最后:

满分代码

#include<cstdio>
#include<iostream>
#include<algorithm>
using namespace std;

typedef struct nzero {
	int index;
	int value;
}nzero;

bool cmp(nzero a, nzero b) {
	return a.index < b.index;
}

nzero u[1000010], v[1000010];

int main() {
	int n, a, b;
	cin >> n >> a >> b;
	for(int i=0; i<a; i++) {
		cin >> u[i].index >> u[i].value;
	}
	for(int i=0; i<b; i++) {
		cin >> v[i].index >> v[i].value;
	}
	//将所有键值对按index升序排列: 
	sort(u, u+a, cmp);
	sort(v, v+b, cmp);
	
	long long sum = 0; //最终的内积结果(不开long long结果会错误) 
    int temp = 0; //v数组下标的指针。临时变量 
	for(int i=0; i<a; i++) {
		while(v[temp].index < u[i].index && temp<b) temp++;
		if(temp >= b) break;
		if(v[temp].index == u[i].index) {
			sum += v[temp].value * u[i].value;
			temp++;
		}
	}
	
	cout << sum;
	return 0;
}

在这里插入图片描述

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

CCF CSP 2020-06-2 “稀疏向量” 解题思路及满分代码(C++11) 的相关文章

随机推荐