首页 > 其他分享 >洛谷 P1102 A-B 数对(二分写法)

洛谷 P1102 A-B 数对(二分写法)

时间:2025-01-11 13:00:06浏览次数:3  
标签:arr 正整数 P1102 ll 数对 num bool 洛谷 include

题目:

P1102 A-B 数对 - 洛谷 | 计算机科学教育新生态

题目背景

出题是一件痛苦的事情!
相同的题目看多了也会有审美疲劳,于是我舍弃了大家所熟悉的A+B Problem,改用A-B了哈哈!

题目描述

给出一串正整数数列以及一个正整数 C,要求计算出所有满足 A−B=C 的数对的个数(不同位置的数字一样的数对算不同的数对)。

输入格式

输入共两行:

  • 第一行,两个正整数 N,C。
  • 第二行,N 个正整数,作为要求处理的那串数。

输出格式

一行,表示该串正整数中包含的满足 A−B=C 的数对的个数。

输入输出样例

输入 #1


4 1
1 1 2 3

输出 #1


3

说明/提示

  • 对于 75% 的数据,1≤N≤2000。
  • 对于 100% 的数据,1≤N≤2×105,0≤ai​<230,1≤C<230。

2017/4/29 新添数据两组

思路:

1.A-B=C,我们可以已知A,C。转化一下就是B=A-C。在数组中找到B个数就是成功匹配的数对,由于这个是连续单调的数组,并且可能会出现多个B,所以我们只需要找到第一个出现B和最后一个出现的B的下标。相减再+1就是B成功匹配的次数。

2.用二分还是太麻烦了,记得要先排序。这种题我更喜欢用哈希表,之前用map写过。有兴趣的可以看看。

代码如下:

#include<iostream>
#include<unordered_set> 
#include<algorithm>
using namespace std;
typedef long long ll;
const ll L = 2*1e5+10;
ll N,C;
ll arr[L];
bool mem[L];
bool is_first(ll num,ll k)
{
	if(num < k)
	return true;
	else
	return false;
}
bool is_final(ll num,ll k)
{
	if(num <= k)
	return true;
	else
	return false;
}
int find_first(ll arr[],ll len,ll k)//找到第一个出现的数字k位置 
{
	ll l = 0,r = len + 1;
	while(l + 1 < r)
	{
		ll mid = (l + r) / 2;
		if(is_first(arr[mid],k))
		l = mid;
		else
		r = mid;
	}
	if(arr[r] == k)
	return r;
	else
	return -1;
}
ll find_final(ll arr[],ll len,ll k)//找到最后一个出现的数字k位置 
{
	ll l = 0,r = len + 1;
	while(l + 1 < r)
	{
		ll mid = (l + r) / 2;
		if(is_final(arr[mid],k))
		l = mid;
		else
		r = mid;
	}
	if(arr[l] == k)
	return l;
	else
	return -1;
}
int main(void)
{
	//缩短输入输出的时间可以不写 
	ios :: sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);
	
	
	ll cnt = 0;
	cin >> N >> C;
	for(ll i = 1 ; i <= N ; i++)
	{
		cin >> arr[i];		  
	}
	sort(arr+1,arr+1+N);
	for(ll i = 1 ; i <= N ; i++)
	{
			if(find_first(arr,N,arr[i] - C) == -1)
			continue;
			else//第一次找到了 
			{
				ll first,final;
			    first =  find_first(arr,N,arr[i] - C); 
//			    cout << arr[i] - C <<"第一个下标:" << first << endl;
				final = find_final(arr,N,arr[i] - C);
//				cout << arr[i] - C << "最后一个下标:" << final << endl;
				cnt = cnt + final - first + 1;
			} 
	}
	cout << cnt;
	return 0;
 } 

标签:arr,正整数,P1102,ll,数对,num,bool,洛谷,include
From: https://blog.csdn.net/zqystca/article/details/145075207

相关文章

  • 洛谷P2181 对角线
    对于一个 ......
  • 719. 找出第 K 小的数对距离
    找出第K小的数对距离数对(a,b)由整数a和b组成,其数对距离定义为a和b的绝对差值。给你一个整数数组nums和一个整数k,数对由nums[i]和nums[j]组成且满足0<=i<j<nums.length。返回所有数对距离中第k小的数对距离。示例1:输入:nums=[1,3,1],k=1......
  • 洛谷题单指南-线段树的进阶用法-P3157 [CQOI2011] 动态逆序对
    原题链接:https://www.luogu.com.cn/problem/P3157题意解读:长度为n的序列,序列是1~n的排列,一共m个删除操作,每一个删除之前输出逆序对。解题思路:要计算静态的逆序对,可以通过树状数组、权值线段树等方式,时间复杂度都是O(nlogn)要计算动态的逆序对,算上每一次删除,暴力做法需要O(mnlo......
  • 洛谷 P3615 如厕计划
    题意:2n个人排队上厕所,有两个厕所,一个男女都可以上,一个只有女的可以上,每个人上厕所都只有一分钟,你可以调整这些人的顺序,每个的怒气值为有多少后面的人排到自己前面了。求可以n分钟上完厕所的情况中,怒气最大的最小。这题看半天没思路,只能看题解。首先厕所一分钟都不能停,要么男女一......
  • 洛谷 P1928 外星密码
    好久不见,随便找一题找找感觉。递归写法:#include<bits/stdc++.h>usingnamespacestd;strings;stringtimes(stringx,intcnt){ stringnewstr=""; while(cnt--)newstr+=x; returnnewstr;}pair<string,int>decompress(intpos){ intnum=0; stringte......
  • 洛谷 P2754 [CTSC1999] 家园 / 星际转移问题——题解
    #ifdefONLINE_JUDGE#else#defineQiu_Cheng#endif#include<bits/stdc++.h>#defineintlonglongusingnamespacestd;//typedeflonglongll;constintN=2e6+5,mod=1e9+7,inf=INT_MAX;//constintmod1=469762049,mod2=998244353,mod3=1004535......
  • 洛谷 P1550 [USACO08OCT] Watering Hole G 题解
     由于无法提交题解所以来csdn蹭个位置  题目链接  这道题我的思路就是用并查集(推荐先学习:并查集(B站视频))将所有农场连接成n个(几个都不重要)连通块,用一个优先队列(由于作者没找视频所以不放链接了sorry)记录x农场连接y农场的最小价格。  有个值......
  • 洛谷题单指南-线段树的进阶用法-P4093 [HEOI2016/TJOI2016] 序列
    原题链接:https://www.luogu.com.cn/problem/P4093题意解读:一个序列,m个变化,求任意一个变化后不受影响的最长上升子序列长度。解题思路:设原序列为a[N],原序列经过变化后能得到的最大值序列为maxa[N],最小值序列为mina[N]设f[i]表示以第i个数结尾的最长不降子序列长度有f[i]=max......
  • 洛谷P2670 [NOIP2015 普及组] 扫雷游戏
    一、原理此代码旨在解决扫雷游戏中根据给定的雷区地雷分布情况,计算出每个非地雷格周围的地雷数量,并输出完整雷区信息的问题。核心原理是通过遍历二维的雷区表示数组,针对每个非地雷格,检查其周围八个方向(上、下、左、右、左上、右上、左下、右下)上的格子是否为地雷格(以 * 表示......
  • 每日一题洛谷B3655 [语言月赛202208] 天天爱跑步C语言
    #include<stdio.h>intmain(){ intn; scanf("%d",&n); intv1,v3,v7,v30,v120,v365; scanf("%d%d%d%d%d%d",&v1,&v3,&v7,&v30,&v120,&v365); intt=0; intcount=0; intsum=0; for......