链接:https://codeforces.com/contest/1283/problem/E
题意: 有n个人住在一些房子里,有的人住在同一个房子里。每个人可以选择搬去他的房子左边那个房子或者右边那个房子,亦或是不搬,搬只能向左或向右移动一次。问这些人最少住几个房子和最多住几个房子。
题解:贪心。最小值就是三人聚合起来,聚合在一个房子。最大值就是贪心地尽可能地向空房子移动
AC代码:
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<vector> using namespace std; const int maxn = 2e5+5 ; int x[maxn]; int s[maxn]; int main(){ int n;cin>>n; for(int i = 0;i<n;i++){ int t;cin>>t; x[t] ++; s[t] ++; } int mx = 0,mi = 0; for(int i = 1;i<=n+1;i++){//求最大值 if(x[i] == 0 ) continue;//当前为0,没人住就跳过 if(x[i-1] == 0 ){//前一个房子为空,就移动过一个人,占一个房子 x[i]--; x[i-1]++; } if(x[i]>1){//往前一个房子移动过一个人后,如果还有多余的人能再移动,就尽可能再往后面的房子移动 x[i+1]++; x[i]--; } } for(int i = 0;i<=n+1;i++){ if(x[i]!=0) mx++; } vector<int> v; int f = 0,cur = 0; for(int i = 1;i<=n;i++){ if(s[i] != 0){//如果当前房子有人,那么房子+1和-1地方的人都聚合过来,每三个人跳转一次 mi++; i+=2;//直接跳转 } } cout<<mi<<" "<<mx; return 0; }