写给自己,也写给大家:把搜过的每一道题弄明白,别欺骗自己,也别辜负自己
问题描述
思路及注意点
思路一:
创建两个数组,初始化为0,把index当作数组下标,输入对应的value,最后for循环相乘两个数组对应的值后累加。
问题:在测试点7、8、9、10中,n的测试点是≤109,对于数组来讲,没办法设立那么长的数组
用这个思路写代码得分为60
思路二:
创建两个二维数组,一行保存两个值,index和value,由于a、b最大值也≤5×105,数组可以有这么长的长度。之后根据index相等进行value相乘后相加,得到最后的结果
①使用双层for循环,运行超时,得分30
②巧妙使用单层循环进行判断index是否相等,正确,得分100
注意:最后的结果要用long long型,因为最后的结果会超出int型所表示的范围。
关键代码(只展示AC的代码)
long long sum=0; //求的内积会超过int所能表示的范围
int i=0,j=0;
while(i<a&&j<b){ //巧妙使用单层for循环解决超时问题
if(aa[i][0]==bb[j][0]){
sum+=(aa[i][1]*bb[j][1]);
i++;
j++;
}
else if(aa[i][0]<bb[j][0])
i++;
else if(aa[i][0]>bb[j][0])
j++;
}
完整代码(只展示AC的代码)
#include<iostream>
using namespace std;
int main(){
int n,a,b; //n为向量维数,a、b分别表示向量中非零值的个数
cin>>n>>a>>b;
int aa[a][2],bb[b][2];
for(int i=0;i<a;i++){
cin>>aa[i][0]>>aa[i][1]; //aa[i][0]:index,表示索引;aa[i][1]:value,表示该索引所对应的非零值
}
for(int i=0;i<b;i++){
cin>>bb[i][0]>>bb[i][1]; //bb[i][0]:index,表示索引;bb[i][1]:value,表示该索引所对应的非零值
}
long long sum=0; //求的内积会超过int所能表示的范围
int i=0,j=0;
while(i<a&&j<b){ //巧妙使用单层for循环解决超时问题
if(aa[i][0]==bb[j][0]){ //索引值相同,则使其相应的非零值相乘
sum+=(aa[i][1]*bb[j][1]);
i++;
j++;
}
else if(aa[i][0]<bb[j][0]) //若第一个向量的索引值小于第二个向量的索引值
i++; //则对第一个向量的下一个非零值进行查询
else if(aa[i][0]>bb[j][0]) //若第一个向量的索引值大于第二个向量的索引值
j++; //则对第二个向量的下一个非零值进行查询
}
cout<<sum;
return 0;
}
//测试用例:
//10 3 4
//4 5
//7 -3
//10 1
//1 10
//4 20
//5 30
//7 40
//坑:1. 数组索引不能用维度表示,数组开不了那么大
//2. 要使用long long,不能用int,求的内积会超过int所能表示的范围
//3. 不能使用双层for循环,会超时
因孤独而沉寂,因沉寂而伟大