51NOD1483

闲着没事打开51nod发现刚添加一道傻逼题,怒抢一血啊……

题目链接:http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1483

做法是对于每一个输入的数,处理出全部它可达的数,并用vis来记录到达i的数的数量已经他们的总步数,最后for一遍,对于所有vis[i] == n的值取min值就可以了。

#include <iostream>
#include <iomanip>
#include <fstream>
#include <sstream>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <cctype>
#include <algorithm>
#include <functional>
#include <numeric>
#include <string>
#include <set>
#include <map>
#include <stack>
#include <vector>
#include <queue>
#include <deque>
#include <list>
using namespace std;
typedef long long ll;
#define PB push_back
#define UB upper_bound
#define LB lower_bound
#define MP make_pair
#define pii pair<int,int>
#define vi vector<int>
#define vii vector<vi>
#define mst(x,y) memset(x,y,sizeof(x))
#define fr(x) freopen(x,"r",stdin)
#define fw(x) freopen(x,"w",stdout)
#define sp system("pause")
#define iin(x) scanf("%d",&x)
#define INF 1e9
#define MAXN 100005
#define hash hhash
#define PI acos(-1.0)
#define eps 1e-4

pii p[100005];

void work(int x)
{
    int st = x,cnt = 0;
    while(st <= 100000)
    {
        p[st].first++;
        p[st].second += cnt++;
        st *= 2;
    }
    st = x,cnt = 0;
    while(st > 0)
    {
        if(st != x)
        {
            p[st].first++;
            p[st].second += cnt;
        }
        if(st % 2 == 1 && st != 1)
        {
            int h = cnt + 2,g = st / 2 * 2;
            while(g <= 100000)
            {
                p[g].first++;
                p[g].second += h++;
                g *= 2;
            }
        }
        cnt++;
        st /= 2;
    }
}

int main()
{
    int n;
    cin >> n;
    int f[100005];
    for(int i = 0;i < n;i++)
        cin >> f[i],work(f[i]);
    int gg = INF;
    for(int i = 1;i <= 100000;i++)
    {
        if(p[i].first == n)
        {
            gg = min(gg,p[i].second);
        }
    }
    cout << gg << endl;
    return 0;
}

热评文章