奇奇怪怪的思路 + 神奇的二分剪枝
查看原帖
奇奇怪怪的思路 + 神奇的二分剪枝
917025
XYzero楼主2024/8/11 20:41
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
#define int long long
const int N = 1e5 + 10;
int a[N],n,tot,ans,X;
bool Ans;
struct Set{
	int l,r;
}s[N];
map<int,int>num;
void solve(int l,int r){
	if(!Ans){
		return ;
	}
	int min_num = INT_MAX;
	int L = a[l],R = a[r];
	for(int i = L;i <= R;i++){
		min_num = min(min_num,num[i]);
	}
	bool flg = true;
	for(int i = L;i <= R;i++){
		num[i] -= min_num;
		if(num[i] != 0)flg = false;
	}
	for(int i = L;i <= R;i++){
		min_num = max(min_num,num[i]);
	}
	ans = min(ans,r - l + 1);
	if(ans < X){
		Ans = false;
	    return ;
	}
	if(flg){
		return ;
	}
	
	int pos = l;
	for(int i = l;i <= r;i++){
		if(a[i] != a[i - 1] && a[i] != a[i - 1] + 1){
			solve(pos,i - 1);
			pos = i;
		}
	}
	solve(pos,n);
	return ;
}
signed main(){
	ios::sync_with_stdio(false);
	cin.tie(0),cout.tie(0);
	
	cin >> n;
	ans = INT_MAX;
	for(int i = 1;i <= n;i++){
		cin >> a[i];
		num[a[i]]++;
	}
	sort(a + 1,a + 1 + n);
	int pos = 1;
	for(int i = 2;i <= n;i++){
		if(a[i] == a[i - 1] || a[i] == a[i - 1] + 1){
			continue; 
		}
		else{
			s[++tot].l = pos,s[tot].r = i - 1;
			pos = i;
		}
		
   }
	s[++tot].l = pos,s[tot].r = n;
    int l = 1 - 1,r = n + 1;
	while(l + 1 < r){
		Ans = true;
		int mid = l + r >> 1;
		X = mid;
		for(int i = 1;i <= tot;i++){
		    solve(s[i].l,s[i].r); 
		    if(!Ans)break;
		}
		if(Ans)l = mid;
		else r = mid; 
	} 
		
	cout << l;
	
	return 0;
} 

不加二分答案有 40pts,突发奇想加了之后还是40pts,不过变成 WA 了,想问有大佬知道哪里错了吗,或者是思路假了

2024/8/11 20:41
加载中...