csp试题2:稀疏向量

csp试题2:稀疏向量

题目

题目描述
      对于一个 n 维整数向量 v∈Zn,其在第 index 个维度上的取值记作 vindex。这里我们约定 index 的取值从 1 开始,即 v=(v1,v2,…,vn)。下面介绍一种向量的稀疏表示方法。
      如果 v 仅在少量维度上的取值不为0,则称其为稀疏向量。
      例如当 n=10 时,v=(0,0,0,5,0,0,-3,0,0,1) 就是一个稀疏向量。
      由于稀疏向量的非零值较少,我们可以通过仅存储非零值的方式来节省空间。具体来说,每个非零值都可以用一个 (index, value)对来表示,即该向量在第 index 个维度上的取值 vindex=value≠0。在上面的例子中,v 就可以表示为[(4,5),(7,-3),(10,1)]。
      接下来给出这种稀疏表示一般化的定义。
      * 对于任意一个 n 维整数向量 v∈Zn,如果其在且仅在 a 个维度上取值不为0,则可以唯一表示为:
p1
      * 其中所有的 index 均为整数且满足:
p2
      * valuei表示向量 v 在对应维度 indexi 上的非零值。
      给出两个 n 维整数向量 u,v∈Zn的稀疏表示,试计算它们的内积。
p3
输入格式
      从标准输入读入数据。
      输入的第一行包含用空格分割的三个正整数 n、a 和 b,其中 n 表示向量 u、v 的维数,a 和 b 分别表示两个向量所含非零值的个数。
      第二行到第 a+1 行输入向量 u 的稀疏表示。第 i+1 行(1 ≤ i ≤ a)包含用空格分割的两个整数 indexi 和 valuei,表示uindexi = valuei ≠ 0。
      第 a+2 行到第 a+b+1 行输入向量 v 的稀疏表示。第 j+a+1 行(1 ≤ j ≤ b)包含用空格分割的两个整数 indexj 和 valuej,表示vindexj = valuej ≠ 0。
输出格式
      输出到标准输出。
      输出一个整数,表示向量 u 和 v 的内积 u·v。
样例
输入:

10 3 4
4 5
7 -3
10 1
1 10
4 20
5 30
7 40

输出:

-20

解释:
      u = (0,0,0,5,0,0,-3,0,0,1)
      v = (10,0,0,20,30,0,40,0,0,0)
      u·v = 5x20 + (-3)x40 = -20
子任务

  • 输入数据保证 0 < a,b < n;
  • 向量 u 和 v 在每一维度上的取值的绝对值 |ui|,|vi|≤106(1≤i≤n)
    p4

分析

      逻辑很简单,主要解决数据量大的问题。

代码

连续两次提交都是满分,都是泪。。。

import java.util.Scanner;

/**
 * csp试题:稀疏向量 202006-2
 * @author dxt
 *
 */
public class Main {
	public static void main(String[] args){
		//1. 接收数据 n, a, b
		int n, a, b;
		Scanner scan = new Scanner(System.in);
		n = scan.nextInt();
		a = scan.nextInt();
		b = scan.nextInt();
		
		//2.1 接收向量 u 的稀疏表示数据
		int[] u_index = new int[a];
		int[] u_value = new int[a];
		for(int i=0; i<a; i++){
			u_index[i] = scan.nextInt();
			u_value[i] = scan.nextInt();
		}
		
		//3. 初始化最后结果
		long result = 0L;
		int v_index, v_value;
		int index_u = 0;
		for(int i=0; i<b; i++){
			v_index = scan.nextInt();	
			v_value = scan.nextInt();
			
			while(index_u < a && i<a && index_u < b){		
				if(u_index[index_u] == v_index){
					result += v_value * u_value[index_u];
					index_u++;
					break;
				}else if(u_index[index_u] < v_index){
					index_u++;
				}else{
					break;
				}
			}
		}
		
		//4. 输出结果
		System.out.println(result);
	}
}

总结

      首先,while判断中加入了i<a后,分数加了10分;然后将保存向量u的数据结构由一个a行2列的矩阵,改成了两个数组,分数加了20分;最后又在while判断中加了index_u < b,期望能在减点运行时间。
      这个问题其实使用map结构会很合适,但我用HashMap写的存在 运行超时 问题。

©️2020 CSDN 皮肤主题: 技术黑板 设计师:CSDN官方博客 返回首页