题意:给你1e6个1e6内的数然后问最多有多少对对子和顺子。顺子至少有3个,当然肯定只用三个。
思路:贪心的做。从小到大枚举,如果,能把当前的全部变成对子,那就直接变成对子。如果多了一个,那就看后两个的情况。后两个如果有一个是0,那就不用考虑这个多余的了。然后对于后两个数有的,分四种情况讨论一下。情况很简单。
#include <cstdio>
#include <cmath>
#include <cstring>
#include <string>
#include <algorithm>
#include <iostream>
#include <vector>
#include <map>
#include <queue>
#include <stack>
using namespace std;
#define push_back pb
#define pi acos(-1)
const long long mod = 1000000007;
#define maxn 111111
#define maxm 11111
using namespace std;
int n;
int vis[1111111];
int main()
{
while(scanf("%d", &n) != EOF) {
int x;
memset(vis, 0, sizeof vis);
for(int i = 1; i <= n; i++) {
scanf("%d", &x);
vis[x]++;
}
long long ans = 0;
for(int i = 1; i <= n; i++) {
if(vis[i]) {
ans += vis[i] / 2;
vis[i] %= 2;
if(vis[i] == 0) continue;
else {
if(!vis[i + 1] || !vis[i + 2]) {
continue;
}
if(vis[i + 1] & 1) {
ans += vis[i + 1] / 2;
vis[i + 1] = 1;
}
else {
ans += vis[i + 1] / 2 - 1;
vis[i + 1] = 2;
}
if(vis[i + 2] & 1) {
ans += vis[i + 2] / 2;
vis[i + 2] = 1;
}
else {
ans += vis[i + 2] / 2 - 1;
vis[i + 2] = 2;
}
if(vis[i + 1] == 1 && vis[i + 2] == 1) {
ans++;
vis[i + 1] = 0;
vis[i + 2] = 0;
continue;
}
if(vis[i + 1] == 1 && vis[i + 2] == 2) {
ans++;
vis[i + 1] = 0;
vis[i + 2] = 1;
continue;
}
if(vis[i + 1] == 2 && vis[i + 2] == 1) {
ans++;
vis[i + 1] = 0;
vis[i + 2] = 1;
continue;
}
if(vis[i + 1] == 2 && vis[i + 2] == 2) {
ans += 2;
vis[i + 1] = 0;
vis[i + 2] = 0;
continue;
}
}
}
}
printf("%d\n", ans);
}
return 0;
}