「csp模式試題 202006-2」稀疏向量 C/C++
目錄
題目
輸入輸出樣例
題解思路
題解原始碼(c/c++)
題目 :稀疏向量
【問題描述】
對於一個 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,則可以唯一表示為:
[(index1,value1),(index2,value2),...,(indexa,valuea)]
其中所有的 index 均為整數且滿足:
1≤index1<index2<...<indexa小於等於n
valuei 表示向量 V 在對應維度上 indexi 上的非零值。
給出兩個 n 維整數向量 U,V∈Zⁿ 的稀疏表示,試計算他們的內積。
U·V=∑ui*vi (i:1->n)
【輸入格式】
從標準輸入讀入資料。
輸入的第一行包含用空格分割的三個正整數 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。
輸入輸出樣例
輸入樣例1
10 3 4
4 5
7 -3
10 1
1 10
4 20
5 30
7 40
輸出樣例1
-20
樣例 1 解釋
U=(0,0,0,5,0,0,-3,0,0,1)
V=(10,0,0,20,30,0,40,0,0)
U·V=5*20 +(-3)*40=-20
【子任務】
輸入資料保證 0<a,b<n;
向量 U 和 V 在每一維度上取值的絕對值|ui|,|vi|≤10^6 (1≤i≤n)
題解思路
看完題目相信你們都會做,但是卻拿不到滿分。原因有以下兩個坑點。
結果
result一定是long long型資料
,因為每個 ui、vi 的絕對值為 10^6,說明中間的結果可能達到 10^12,如果不使用 long long 型資料就會造成資料溢位。從而答案不正確。
只需要用陣列記錄第一組向量 U 的資料,在第二組資料輸入的時候就可以直接判斷進行處理。這樣可以節省空間和時間,避免超時。
使用一個 U 向量的
記錄型指標pointer
進行輔助處理。
題解(c/c++)
#include <iostream>
using namespace std;
struct P
{
int index,value;
};
int main() {
int n, a, b;
cin >> n >> a >> b;
struct P U[a + 1];
for (int i = 0; i < a; i++) {
cin >> U[i].index >> U[i].value;
}
long long result = 0; //取值的絕對值為10^6,乘積為10^12,必須用long long型
int pointer = 0; //U向量的記錄型指標
int index, value;
for (int i = 0; pointer < a && i < b; i++) {
cin >> index >> value;
while (pointer < a && index > U[pointer].index) pointer++;
if (index > U[a - 1].index) break; //如果V向量輸入的index大於了U向量最大的index,後面的全是0不用考慮
if (pointer >= a) break; //U向量對應的資料已經計算完,後面V向量的輸入不用再考慮
if (index == U[pointer].index) result += U[pointer++].value * value;//計算完後pointer指標增1
}
cout << result;
}