P4447 [AHOI2018初中组]分组 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)
一开始看到这题,十分想当然的以为只要排个序,然后找到连续的最短的数组就行,然而事实证明我想简单了。。。
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 1e5 + 10;
ll a[N], s[N];
stack<int>st[N];
int main() {
ll n, t = 0, min = (1 << 31) - 1;
int c = 0;
cin >> n;
for (int i = 0; i < n; i++)
cin >> a[i];
sort(a, a + n);
for (int i = 0; i < n; i++) {
for (int j = t; j > 0; j--) {//遍历以前建过的栈
if (st[j].top() + 1 == a[i]) {//如果和之前建立的某个栈中的数能连续起来,就放进去
st[j].push(a[i]);
c = 1;
break;
} else
c = 0;
}
if (c == 0)
st[++t].push(a[i]);//否则就重新建一个栈
}
for (int i = 1; i <= t; i++) {
if (st[i].size() < min) {
min = st[i].size();
}
}
cout << min << endl;
return 0;
}
分析:入栈条件--->st[i].top()+1==a[i];
重点:如果多个栈满足条件,应选择后建立的栈,因为后建立的栈元素少
第一次的错误代码:
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 1e6 + 10;
ll a[N], s[N];
int main() {
ll n;
cin >> n;
for (int i = 0; i < n; i++)
cin >> a[i];
sort(a, a + n);
ll l = 0, ans = 1;
for (int i = 0; i < n; i++) {
if (a[i + 1] - a[i] == 1)
ans++;
else {
s[l++] = ans;
ans = 1;
}
}
sort(s, s + l);
cout << s[0] << endl;
return 0;
}
错因:如果遇到相同值的元素会直接跳过(被抛弃),后期也不会用,但是第一种方法则是会吧之前建的栈挨个遍历(防止相同元素被抛弃的情况)