2017藍橋杯C++B組 國賽
個人理解,僅供參考,歡迎討論
(5)
標題:對局匹配
小明喜歡在一個圍棋網站上找別人線上對弈。這個網站上所有註冊使用者都有一個積分,代表他的圍棋水平。
小明發現網站的自動對局系統在匹配對手時,只會將積分差恰好是K的兩名使用者匹配在一起。如果兩人分差小於或大於K,系統都不會將他們匹配。
現在小明知道這個網站總共有N名使用者,以及他們的積分分別是A1, A2, … AN。
小明想了解最多可能有多少名使用者同時線上尋找對手,但是系統卻一場對局都匹配不起來(任意兩名使用者積分差不等於K)?
輸入
第一行包含兩個個整數N和K。
第二行包含N個整數A1, A2, … AN。
對於30%的資料,1 <= N <= 10
對於100%的資料,1 <= N <= 100000, 0 <= Ai <= 100000, 0 <= K <= 100000
輸出
一個整數,代表答案。
樣例輸入:
10 0
1 4 2 8 5 7 1 4 2 8
樣例輸出:
6
再比如,
樣例輸入:
10 1
2 1 1 1 1 4 4 3 4 4
樣例輸出:
8
資源約定:
峰值記憶體消耗 < 256M
CPU消耗 < 1000ms
請嚴格按要求輸出,不要畫蛇添足地列印類似:“請您輸入…” 的多餘內容。
所有程式碼放在同一個原始檔中,除錯通過後,拷貝提交該原始碼。
注意: main函式需要返回0
注意: 只使用ANSI C/ANSI C++ 標準,不要呼叫依賴於編譯環境或作業系統的特殊函式。
注意: 所有依賴的函式必須明確地在原始檔中 #include , 不能通過工程設定而省略常用標頭檔案。
提交時,注意選擇所期望的編譯器型別。
把不能出現的人連成一條鏈,dp[i][0]表示不選第i個人的最多人數,dp[i][1]表示選第i個人的最多人數,則 dp[[i][0]=max(dp[pre][1],dp[pre][1]), dp[i][1]=dp[pre][0]+a[u];
#include <cstdio>
#include <algorithm>
#include <cstdlib>
#include <bits/stdc++.h>
typedef long long LL;
const int N =1e5+100;
using namespace std;
typedef long long LL;
const LL mod = 1000000009;
int a[N], vis[N];
vector<int>p[N];
int ans;
int dp[N][3];
void dfs(int u,int pre)
{
dp[u][1]=a[u]+dp[pre][0];
dp[u][0]=max(dp[pre][1],dp[pre][0]);
ans=max(max(dp[u][1],dp[u][0]),ans);
vis[u]=1;
for(int i=0;i<p[u].size();i++)
{
int v=p[u][i];
if(!vis[v])
{
dfs(v,u);
}
}
return ;
}
int main()
{
memset(a,0,sizeof(a));
int n, k;
scanf("%d %d", &n, &k);
for(int i=1; i<=n; i++)
{
int x;
scanf("%d", &x);
a[x]++;
}
if(k==0)
{
int num=0;
for(int i=1; i<=n; i++)
if(a[i]!=0)num++;
cout<<num<<endl;
}
else
{
for(int i=0;i+k<=100000;i++)
{
if(a[i]!=0&&a[i+k]!=0)
p[i].push_back(i+k),p[i+k].push_back(i);
}
int num=0;
memset(vis,0,sizeof(vis));
memset(dp,0,sizeof(dp));
for(int i=0;i<=100000;i++)
{
if(a[i]!=0&&vis[i]==0)
{
ans=0;
dfs(i,100001);
num+=ans;
}
}
cout<<num<<endl;
}
return 0;
}