Limite de temps : 1000 MS | Limite de mémoire : 65 536 Ko | |
Total des soumissions : 31 958 | Accepté : 10375 |
Description
Dans un certain cours, vous passez n tests. Si vous obtenez ai des questions bi correctes au test i , votre moyenne cumulée est définie comme étant
.
Compte tenu de vos résultats aux tests et d'un entier positif k , déterminez jusqu'où vous pouvez atteindre votre moyenne cumulée si vous êtes autorisé à laisser tomber l'un de vos résultats aux tests.
Supposons que vous passiez 3 tests avec des scores de 5/5, 0/1 et 2/6. Sans abandonner aucun test, votre moyenne cumulée est de
. Cependant, si vous abandonnez le troisième test, votre moyenne cumulée devient .
Saisir
Le fichier de test d'entrée contiendra plusieurs cas de test, chacun contenant exactement trois lignes. La première ligne contient deux entiers, 1 ≤ n ≤ 1000 et 0 ≤ k < n . La deuxième ligne contient n entiers indiquant ai pour tout i . La troisième ligne contient n entiers positifs indiquant bi pour tout i . Il est garanti que 0 ≤ ai ≤ bi ≤ 1 000 000 000. La fin de fichier est marquée par un scénario de test avec n = k = 0 et ne doit pas être traitée.
Sortir
Pour chaque cas de test, écrivez une seule ligne avec la moyenne cumulée la plus élevée possible après avoir supprimé k des résultats de test donnés. La moyenne doit être arrondie à l’entier le plus proche.
Exemple d'entrée
3 1 5 0 2 5 1 6 4 2 1 2 7 9 5 6 7 9 0 0
Exemple de sortie
83 100
Indice
Pour éviter les ambiguïtés dues aux erreurs d'arrondi, les tests de jugement ont été construits de manière à ce que toutes les réponses soient éloignées d'au moins 0,001 d'une limite de décision (c'est-à-dire que vous pouvez supposer que la moyenne n'est jamais de 83,4997).
Idées :
sur le sujet
Pour simplifier, essayez de trouver le x inférieur à .
Le point final gauche est 0 et le point final droit est la somme cumulée de ai. Il s'agit d'une recherche binaire efficace.
Lors de la réalisation d’une dichotomie, il est également nécessaire de déterminer si elle est monotone.
#include<stdio.h>
#include<algorithm>
#include<iostream>
using namespace std;
struct Pair {
int a, b;
double y;
}p[1005];
bool cmp(Pair a, Pair b) {
return a.y > b.y; // 从大到小
}
int n, k;
bool check(double x) {
for (int i = 0; i < n; i++) {
p[i].y = p[i].a * 1.0 - x * p[i].b; // y = a - x*b 在x轴小点的值
}
sort(p, p + n, cmp);
double f = 0;
for (int i = 0; i < k; i++) f += p[i].y;
return f < 0;
}
int main() {
while (cin >> n >> k, n + k) {
k = n - k; // 选出 k 对
for (int i = 0; i < n; i++) cin >> p[i].a;
for (int i = 0; i < n; i++) cin >> p[i].b;
double L = 0, R = 0;
for (int i = 0; i < n; i++) R += p[i].a;
for (int i = 0; i < 50; i++) {
double mid = L + (R - L) / 2;
if (check(mid)) R = mid;
else L = mid;
}
printf("%d\n", (int)(100 * (L + 0.005)));
}
return 0;
}