cf 568 div2 c1 c2
题意:
有n个学生要考试,总的考试时间是M,每个学生考试需要\(t_i\)的时间,每次只能一个学生进行考试。问如果学生要完成考试,那么在他前面至少有多少人不能参加考试?
题解:
就是求一个序列前面最多多少个数相加少于等于( m - \(a_i\) )
c1数据范围比较小,然后今天又恰好看到了小灰公众号讲了插入排序,就用上了。保证\(a_i\)前面的序列是有序的,然后从后往前一直减,直到符合要求。但是时间复杂度是O(\(n^2\)),c2的数据是肯定过不了的,然后我没想到怎么写!!看了题才发现\(t_i\)<=100,可以直接记录\(t_i\)的数量,然后从小到大扫一遍,时间复杂度O(n*100)(2 * \(10^6\))
//c1
#include <cstdio>
int main() {
int n, m, a[110], sum = 0;
scanf("%d %d", &n, &m);
for(int i = 0; i < n; i++) {
int cnt = 0;
scanf("%d", &a[i]);
if(sum > m - a[i]) {
int summ = sum, j = i - 1;
while(summ > m - a[i]) {
cnt++;
summ -= a[j];
j--;
}
}
int b = a[i], j = i - 1;
if(i) {
while(b < a[j] && j >= 0) {
a[j+1] = a[j];
j--;
}
a[j+1] = b;
}
sum += b;
printf("%d ", cnt);
}
printf("\n");
return 0;
}
//c2
#include <cstdio>
int cnt[110];
int main() {
int n, m, a, sum = 0;
scanf("%d %d", &n, &m);
for(int i = 0; i < n; i++) {
scanf("%d", &a);
sum += a;
int ans = 0;
if(sum > m) {
int summ = a;
for(int i = 1; i <= 100; i++) {
if(cnt[i]) {
if(summ + cnt[i] * i < m) {
ans += cnt[i];
summ += cnt[i] * i;
}
else {
ans += (m - summ) / i;
break;
}
}
}
}
else ans = i;
cnt[a]++;
printf("%d ", i - ans);
}
return 0;
}