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

原本我直接用模擬來走,找出符合要求的但是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;
}

 

發佈了168 篇原創文章 · 獲贊 3 · 訪問量 3404
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章