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
原本我直接用模擬來走,找出符合要求的但是wa了,搜題解後發現那是個假算法。。。
正確思路應該是找符合要求的區間;;;
可行區間
1:9~16
2:9~24
9:10~80
10:10~88
11:10~96
16:10~136
17:11~144
11110:1397~88888
11112:1397~88888
88888:11103~88888
88889:88888~100000
100000:88888~100000
找左右臨界值就是找規律,注意最後要判斷自己是不是在區間裏面,畢竟自己不能給自己發郵件。。。。(第一次沒考慮到)
#include<cstdio>
#include<cstdlib>
#include<iostream>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<string>
#include<queue>
#include<vector>
#define pi 3.1415926
#define inf 0x3f3f3f3f
using namespace std;
const long long mod = 1e9 + 7;
#define ll long long
#define MAXN 1000005
//char s[MAXN],t[MAXN];
int a[MAXN];
int main()
{
int n;
cin >> n;
for (int i = 0; i < n; i++)
{
scanf("%d", &a[i]);
} sort(a, a + n);
long long ans = 0;
for (int i = 0; i < n; i++)
{
int v1;
if (a[i] / 8 * 8 == a[i])
{
v1 = a[i] / 8 + 8;
}
else
{
v1 = a[i] / 8 + 9;
}
int v2 = 8 * a[i] + 8;
if (a[i] < 88888)
{
v2 = min(v2, 88888);
}
int sign = upper_bound(a, a + n, v2) - lower_bound(a, a + n, v1);
if (a + i >= lower_bound(a, a + n, v1) && a + i < upper_bound(a, a + n, v2))sign -= 1; //自己在區間裏面
sign = max(0, sign);
ans += sign;
}
cout << ans << endl;
return 0;
}