(Après quelques modifications importantes :)
Si vous n'avez que 2 votants, vous ne pouvez générer que les pourcentages suivants pour les candidats A et B :
0+100, 100+0, or 50+50
Si vous avez 3 votants, alors vous avez
0+100, 100+0, 33.33+66.67, 66.67+33.33 [notice the rounding]
C'est un problème amusant sur les fractions.
Si vous pouvez faire 25%, vous devez alors avoir au moins 4 personnes (vous pouvez donc faire 1/4, car 1/2 et 1/3 ne suffiront pas). Vous pouvez le faire avec plus (c'est-à-dire 2/8 = 25%) mais le problème demande le moins.
Cependant, des fractions plus intéressantes nécessitent des nombres supérieurs à 1 au numérateur :
2/5 = 40%
Puisque vous ne pouvez pas l'obtenir avec autre chose qu'un 2 ou plus au numérateur (1/x ne suffira jamais).
Vous pouvez comparer à chaque étape et augmenter soit le numérateur soit le dénominateur, ce qui est beaucoup plus efficace que d'itérer sur l'ensemble de l'espace d'échantillonnage pour j et d'incrémenter ensuite i ;
Par exemple, si vous avez un pourcentage de 3%, vérifier toutes les solutions à la manière de 96/99, 97/99, 98/99 avant même d'arriver à x/100 est une perte de temps. Au lieu de cela, vous pouvez incrémenter le numérateur ou le dénominateur en fonction du résultat de votre estimation actuelle (supérieur ou inférieur à), comme suit
int max = 5000; //we only need to go half-way at most.
public int minVoters (double onePercentage) {
double checkPercentage = onePercentage;
if (onePercentage > 50.0)
checkPercentage = 100-onePercentage; //get the smaller percentage value
double i=1;
double j=1; //arguments of Math.round must be double or float
double temp = 0;
while (j<max || i<max-1) { //we can go all the way to 4999/5000 for the lesser value
temp = (i/j)*100;
temp = Math.round(temp);
temp = temp/100;
if (temp == checkPercentage)
return j;
else if (temp > checkPercentage) //we passed up our value and need to increase the denominator
j++;
else if (temp < checkPercentage) //we are too low and increase the numerator
i++;
}
return 0; //no such solution
}
Exemple pas à pas pour trouver le dénominateur qui peut donner 55%.
55/100 = 11/20
100-55 = 45 = 9/20 (checkPercentage will be 45.0)
1/1 100.0%
1/2 50.00%
1/3 33.33%
2/3 66.67%
2/4 50.00%
2/5 40.00%
3/5 60.00%
3/6 50.00%
3/7 42.86% (too low, increase numerator)
4/7 57.14% (too high, increase denominator)
4/8 50.00%
4/9 44.44%
5/9 55.56%
5/10 50.00%
5/11 45.45%
6/11 54.54%
6/12 50.00%
6/13 46.15%
6/14 42.86%
7/14 50.00%
7/15 46.67%
7/16 43.75%
8/16 50.00%
8/17 47.06%
8/19 42.11%
9/19 47.37%
9/20 45.00% <-bingo
Ce qui est bien avec cette méthode, c'est qu'elle prend seulement (i+j) étapes où i est le numérateur et j est le dénominateur.