算法巧解:csp稀疏向量:使用map(键值对)

1、事件起源于csp一算法题目稀疏向量

在这里插入图片描述

2、然后我写出代码版本一

这个代码很简单,就是简单模拟一下,使用两个数组,分别存储两个向量,最后再遍历一下就ok ,但是只有60分,因为该存储方式是将稀疏向量恢复为不稀疏的向量存储的,导致在测试最大的几个数据项的时候内存不够用

#include <cstdio>
using namespace std;
int main(){
	long long n;
	int u,v;
	scanf("%d%d%d",&n,&u,&v);
	int uarr[n+1]={0};
	int varr[n+1]={0};
	for(int i=0;i<u;i++){
		int a;
		scanf("%d",&a);	
		scanf("%lld",&uarr[a]);
	}
	for(int i=0;i<v;i++){
		int a;
		scanf("%d",&a);	
		scanf("%lld",&varr[a]);
	}
	//get the mutiple of u and v
	long long res=0;
	for(int i=1;i<n+1;i++){
		if(uarr[i]!=0 && varr[i]!=0){
			res+=uarr[i]*varr[i];
		}
	}
	printf("%lld",res);
}

3、然后我使用map来只存取必要的数据

解决了之前内存不够的问题,但是运行时间超时,还是只有60分,原因是//get the mutiple of u and v(遍历)处的时间花费过多。

#include <cstdio>
#include <map> 
using namespace std;
int main(){
	int n,u,v;
	scanf("%d%d%d",&n,&u,&v);
	map<int,int>m_map1;
	map<int,int>m_map2;
	for(int i=0;i<u;i++){
		pair<int,int>m_pair;
		scanf("%d",&m_pair.first);
		scanf("%d",&m_pair.second);
		m_map1.insert(m_pair);
	}
	for(int i=0;i<v;i++){
		pair<int,int>m_pair;
		scanf("%d",&m_pair.first);
		scanf("%d",&m_pair.second);
		m_map2.insert(m_pair);
	}
	//get the mutiple of u and v
	long long res=0;
	for(int k=0;k<n+1;k++){//method one :runtime error
			if(m_map1.count(k)&&m_map2.count(k)){
				res+=m_map1[k]*m_map2[k];
			}
	}
	printf("%lld",res);
}

4、然后进一步进行改进

省去遍历的操作,在输入第二个向量的时候就得出结果,成功100分

#include <cstdio>
#include <map> 
using namespace std;
int main(){
	int n,u,v;
	scanf("%d%d%d",&n,&u,&v);
	map<int,int>m_map1;
	for(int i=0;i<u;i++){
		pair<int,int>m_pair;
		scanf("%d",&m_pair.first);
		scanf("%d",&m_pair.second);
		m_map1.insert(m_pair);
	}
	//get the mutiple of u and v
	long long res=0;
	for(int i=0;i<v;i++){
		pair<int,int>m_pair;
		scanf("%d",&m_pair.first);
		scanf("%d",&m_pair.second);
		if(m_map1.count(m_pair.first)){
			res+=m_pair.second*m_map1[m_pair.first];
		}
	}
	printf("%lld",res);//must be %lld
}

5、其实还可以进一步优化

省去每次都要创建一个新pair

#include <cstdio>
#include <map> 
using namespace std;
int main(){
	int n,u,v;
	scanf("%d%d%d",&n,&u,&v);
	int first,second;
	map<int,int>m_map1;
	for(int i=0;i<u;i++){
		scanf("%d%d",&first,&second);
		m_map1[first]=second;
	}
	//get the mutiple of u and v
	long long res=0;
	for(int i=0;i<v;i++){
		scanf("%d%d",&first,&second);
		if(m_map1.count(first)){
			res+=second*m_map1[first];
		}
	}
	printf("%lld",res);
	return 0;
}

6、总结一下吧

1、map可以用来创建键值对,结构体也可以,但是结构体不提供对键的随机访问,map可以通过这点来提升速度。
2、map一般通过insert(pair)来插入值,但直接使用键值对也可以
3、在需要对两个数组进行操作时,我们可以在存储第一个数组后,在输入第二个数组的时候进行对结果的操作。以减少运行时间

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值