Example 1 input 8 1 2 7 3 4 8 5 6 output 7 Example 2 input 6 25 1 2 3 14 36 output 2
题目大意:
MAX假定鲨鱼连续几天没游过k米(严格小于k),这几天游过的点视作同一块岛屿,现在问:选取一个最小 的k,使得岛屿数,并且在每一块岛屿所花的天数相等
分析:
以a[i]从小到大进行筛选,用并查集的思想,将a[i]中小于k的天数合并成一块岛,再在所有的k里选择一个最 优解,但是必须注意,要检查下这个岛屿数是不是合法的
code:
#define debug #include<bits/stdc++.h> #define pb push_back #define dbg(x) cout<<#x<<" = "<<(x)<<endl; #define lson l,m,rt<<1 #define cmm(x) cout<<"("<<(x)<<")"; #define rson m+1,r,rt<<1|1 using namespace std; typedef long long ll; typedef pair<int,int> pii; typedef pair<ll,ll>PLL; typedef pair<int,ll>Pil; const ll INF = 0x3f3f3f3f; const ll inf=0x7fffffff; const double eps=1e-8; const int maxn =1e6+10; const int N = 510; const ll mod=1e9+7; const ll MOD=1e9; //------ //define int pre[maxn],sz[maxn],cnt[maxn]; int tot,ans,res; struct node { int val,id; node(int val=0,int id=0):val(val),id(id) {} bool operator <(const node &a)const { return val<a.val; } } v[maxn]; //findset int findset(int x) { return pre[x]==x?x:findset(pre[x]); } //unite void unite(int x,int y) { int px=findset(x),py=findset(y); if(px==py)return; cnt[sz[px]]--; cnt[sz[py]]--; pre[px]=py; sz[py]+=sz[px]; cnt[sz[py]]++; tot--; } //init void init(int n){ for(int i=1;i<=n+1;i++){ pre[i]=i; } } //solve void solve() { int n; while(cin>>n) { ans=res=0; for(int i=0; i<n; i++) { int val; cin>>val; v[i]=node(val,i+1); } init(n); sort(v,v+n); tot=0; for(int i=0;i<n;i++){ int ind=v[i].id; sz[findset(ind)]++; tot++; cnt[sz[findset(ind)]]++; if(sz[findset(ind-1)]){ unite(ind,ind-1); } if(sz[(findset(ind+1))]){ unite(ind,ind+1); } if(cnt[sz[findset(ind)]]==tot&&tot>ans){ ans=tot; res=v[i].val; } } cout<<res+1<<endl; memset(sz,0,sizeof(sz)); memset(cnt,0,sizeof(cnt)); } } int main() { ios_base::sync_with_stdio(false); #ifdef debug freopen("in.txt", "r", stdin); // freopen("out.txt","w",stdout); #endif cin.tie(0); cout.tie(0); solve(); /* #ifdef debug fclose(stdin); fclose(stdout); system("out.txt"); #endif */ return 0; }