数对问题

10 篇文章 0 订阅
7 篇文章 0 订阅

时间限制:1000MS 代码长度限制:10KB
提交次数:0 通过次数:0

题型: 编程题 语言: 不限定

Description

一个长度为N的正整数序列,现在需要计算出有多少对数字的差的绝对值为C。
注意只要位置不同就认为是不相同的数对。

输入格式

第一行,两个整数 N, C。(1=<N<=10000),(1=<C<=10000)
第二行,N个正整数a1…an。 (1=<ai<=10000)

输出格式

仅一行,满足条件的数对的个数。

输入样例

4 1
1 2 3 1

输出样例

3

提示

(a1,a2),(a2,a3),(a2,a4)共3个数对满足条件。

解题思路:先将输入的数据按照升序排序,然后遍历每一个数据,查看其右边是否存在某个数使其满足(ax-ak==c)的条件,如果满足的话,就记录该种数,同时记录该种数的时候应该要看该数有多少个,因为两两数据是可以相等的。在查看是否存在满足条件数的时候,可以使用二分查找进行加速。

#include<iostream>
#include<algorithm>
using namespace std;
int a[10005],n,c,v[10005];//v数组记录值为x的元素个数 
int main()
{
	int i,count=0,low,high,middle;
	ios::sync_with_stdio(false);
	cin>>n>>c;
	for(i=1;i<=n;i++)
	{
	   cin>>a[i];
	   v[a[i]]++;
	}
	sort(a+1,a+1+n);
	/*if(c==0) 
	{
		for(i=1;i<=maxv;i++)
		count+=(v[i]-1)*v[i]/2;
		cout<<count;
		return 0;
	}
	*/
	for(i=1;i<n;i++)
	{
		low=i+1;
		high=n;
		while(low<=high)
		{
			middle=(low+high)/2;
		//	cout<<middle<<endl;
			if(a[middle]-a[i]==c)
			{
				count+=v[a[middle]];
				break;
			}
			
			else if(a[middle]-a[i]>c)
			high=middle-1;
			else
			low=middle+1;
		}
	}
	cout<<count;
	return 0;
 } 

时间限制:1000MS 代码长度限制:10KB
提交次数:0 通过次数:0

题型: 编程题 语言: 不限定

Description

此题目与数对问题一的唯一区别为序列中元素的取值范围。
一个长度为N的正整数序列,现在需要计算出有多少对数字的差的绝对值为C。
注意只要位置不同就认为是不相同的数对。

输入格式
第一行,两个整数 N, C。(1=<N<=10000),(1=<C<=10000)

第二行,N个正整数a1…an。 ai为int范围内的正整数。

输出格式
仅一行,满足条件的数对的个数。

输入样例
4 1
1 2 3 1

输出样例
3

提示
(a1,a2),(a2,a3),(a2,a4)共3个数对满足条件。

**解题思路 :int的取值范围为:-21474836482147483647[-2^312^31-1] 。把桶数组开得更大进行计数即可,其余与上题相同。**

正确思路:把数组开得那么大其实是不现实的,虽然还是过了oj.
因此我们用stl中的map来做,即枚举区间的终点i从1到n,而起点不变。
看看在i-1个元素之内有多少是跟a[i]的绝对值满足条件的。

错误示范:

#include<iostream>
#include<algorithm>
using namespace std;
int a[10005],n,c,v[220000005];//v数组记录值为x的元素个数 
int main()
{
	int i,count=0,low,high,middle;
	ios::sync_with_stdio(false);
	cin>>n>>c;
	for(i=1;i<=n;i++)
	{
	   cin>>a[i];
	   v[a[i]]++;
	}
	sort(a+1,a+1+n);
	/*if(c==0) 
	{
		for(i=1;i<=maxv;i++)
		count+=(v[i]-1)*v[i]/2;
		cout<<count;
		return 0;
	}
	*/
	for(i=1;i<n;i++)
	{
		low=i+1;
		high=n;
		while(low<=high)
		{
			middle=(low+high)/2;
		//	cout<<middle<<endl;
			if(a[middle]-a[i]==c)
			{
				count+=v[a[middle]];
				break;
			}
			
			else if(a[middle]-a[i]>c)
			high=middle-1;
			else
			low=middle+1;
		}
	}
	cout<<count;
	return 0;
 }

参考代码:

#include<bits/stdc++.h>
using namespace std;
int main()
{
	int i,j,x,c,n,m,ans=0,a[200005];
	cin>>n>>c;
	map<int ,int>mp;
	for(i=1;i<=n;i++)
	{
		cin>>a[i];
		ans+=mp[a[i]-c]+mp[a[i]+c];
		mp[a[i]]++;
	}
	cout<<ans;
	return 0;
 } 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值