直接用暴力解法,把小于等于最大数的数字都试一遍。
// 312C
#include <iostream>
#include <memory.h>
#include <stdio.h>
using namespace std;
struct link{
int num;
link* next;
link(int no, link* n) : num(no), next(n) {}
link() : next(NULL) {}
};
struct list{
link *head, *tail;
list(){
head = tail = new link();
}
~list(){
link *tmp = head;
while (tmp) {
head = head->next;
delete tmp;
tmp = head;
}
}
void append(int x){
tail = tail->next = new link(x, NULL);
}
};
int chem[100100];
int indi[100100];
int main(){
int n, i;
cin >> n;
int max = 0;
for (i = 0; i <= n - 1; i++) {
cin >> chem[i];
if (chem[i] > max) max = chem[i];
}
int t = 2;
memset(indi, 0, sizeof(indi));
for (i = 1; t <= 100100; i++, t <<= 1) indi[t] = i;
int tmax = max;
list ls;
while (tmax > 0){
ls.append(tmax);
tmax--;
//tmax >>= 1;
}
link* cur = ls.head;
int min_step = -1;
while (cur->next){
int cur_step = 0;
int reachable = 1;
for (i = 0; i <= n - 1; i++){
int step = 0;
if (cur->next->num > chem[i]){
if (cur->next->num % 2 != 0){
reachable = 0;
break;
}
int t = chem[i];
while (t > 0){
if (cur->next->num % t == 0 && indi[cur->next->num / t]){
step += indi[cur->next->num / t];
break;
}
t >>= 1;
step++;
}
if (t == 0){
reachable = 0;
break;
}
cur_step += step;
}
else if (cur->next->num < chem[i]){
int t = chem[i];
while (t > 0 && t > cur->next->num){
t >>= 1;
step++;
}
if (t == cur->next->num) cur_step += step;
else {
while (t > 0){
if (cur->next->num % t == 0 && indi[cur->next->num / t]){
step += indi[cur->next->num / t];
break;
}
t >>= 1;
step++;
}
if (t == 0){
reachable = 0;
break;
}
else cur_step += step;
}
}
}
if (reachable){
if (min_step == -1) min_step = cur_step;
else if (cur_step < min_step) min_step = cur_step;
//cout << "Target: " << cur->next->num << endl;
//cout << "Steps: " << cur_step << endl;
cur = cur->next;
}
else {
link* tmp = cur->next;
cur->next = tmp->next;
delete tmp;
}
}
cout << min_step << endl;
//system("pause");
return 0;
}