HihoCoder - 1607 H星人社交网络

题目:
Handbook是H星人的一家社交网络。Handbook中共有N名用户,其中第i名用户的年龄是Ai。
根据H星人的文化传统,用户i不会给用户j发送好友请求当且仅当:

  1. Aj < 1/8 * Ai + 8 或者
  2. Aj > 8 * Ai + 8 或者
  3. Ai < 88888 且 Aj > 88888
    其他情况用户i都会给用户j发送好友请求。
    你能求出Handbook总计会有多少好友请求吗?
    Input
    第一行一个整数N。
    第二行N个整数A1, A2, … AN。
    对于30%的数据,1 ≤ N ≤ 100
    对于100%的数据,1 ≤ N ≤ 100000, 1 ≤ Ai ≤ 100000
    Output
    输出Handbook中好友请求的总数
    Sample Input
    2
    10 80
    Sample Output
    1

代码如下:

#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
#define maxn 100005
int a[maxn];
int main()
{
	int n,l,r;
	long long ans;
	cin >> n;
	for(int i = 1;i <= n;i++) cin >> a[i];
	l = r = 1;
	ans = 0;
	sort(a + 1,a + n + 1); 
	for(int i = 1;i <= n;i++){
		while(8 * (a[l] - 8) < a[i] && l <= n) l++;//找区间左端点 
		if(a[i] < 88888){//找区间右端点 
			while(a[r] <= 88888 && a[r] <= 8 * a[i] + 8 && r <= n) r++;
		}
		else{
			while(a[r] <= 8 * a[i] + 8 && r <= n) r++;
		}
		ans += r - l;//区间[l,r)都是年龄a[i]可以发消息的 
		if(i >= l && i < r) ans--;//因为自己不能给自己发消息 
	}
	cout << ans << endl;
	return 0;
}

题意:
给你n个用户年龄,要计算这n个人之间可以发消息的有几对,i不能给j发消息要满足三条规则。
思路:
为了初始双指针这个概念,我选择做了这道题。如果用暴力去做只能通过30%的数据,所以我们要想办法降低复杂度,我们先把这n个用户从小到大排序,我们可以知道i不能给j通信只要满足Aj < 1/8 * Ai + 8或者Aj > 8 * Ai + 8,那么反过来想如果i能给j通信只要j用户的年龄满足在[ai / 8 + 8,8 * ai +8],这里我们用l,r来代表区间的左端点和右端点。然后r - l就是用户i能通讯的人数,如果用户i的年龄在区间里还要减去1,因为自己不能和自己通信。

随着枚举的用户年龄上升,可行区间也在右移。现在对双指针稍微有点初步的概念了,个人认为双指针就是区间的左右端点。

猜你喜欢

转载自blog.csdn.net/qq_41998938/article/details/88748699