codeforces 558C Amr and Chemistry

本文记录了一次编码竞赛的经历,作者分享了在解决一个特定问题时所遇到的困难及最终采用的有效策略。文章强调了直接统计而非二分搜索的重要性,并通过具体的代码示例展示了这一过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

// 仅以此题,记录自己最笨拙的时刻
// 都怪自己太笨,实在是对自己无语
// 不必二分的题目,搞得自己非得二分,
// 你说二分就二分吧,还总是第71组超时
// 最后直接统计,过了。。。
// 还有,突然断电,这串代码啥都没了。。。。
// 继续练吧,趁着年轻

#include <cstdio>
#include <cstring>
#include <vector>
#include <algorithm>
#include <iostream>
using namespace std;
const int maxn = 108000;

int a[maxn];

bool flag[maxn];

struct node {
    int n;
    int t;

    node(){

    }

    node(int n,int t):n(n),t(t){

    }
};
node q[maxn*5];
int temp[maxn];
int c[maxn];
int s[maxn];
int mark;
vector<node> v[maxn];
int n;
int cnt;
int mi;
bool cmp(int a,int b){
    return a > b;
}

bool cmp2(node a,node b){
    return a.n<b.n;
}



void input(){
    mi = -1;
    for (int i=1;i<=n;i++){
        scanf("%d",&a[i]);
        if (mi<a[i])
            mi = a[i];
        v[i].clear();
    }
    memset(c,0,sizeof(c));
    memset(s,0,sizeof(s));
    sort(a+1,a+n+1,cmp);

    for (int i=1;i<=n;i++){
        memset(flag,0,sizeof(flag));
        int head=0,tail = 0;
        q[tail].n = a[i];
        q[tail++].t = 0;
        flag[a[i]] = 1;
        c[a[i]]++;
        while(tail>head){
            int u = q[head].n;
            int tim = q[head++].t;
            //v[i].push_back(node(u,tim));
            if ((u>>1)>=1 && !flag[u>>1]){
                flag[u>>1] = 1;
                c[u>>1]++;
                s[u>>1] += tim + 1;
                q[tail].n = u>>1;
                q[tail++].t = tim+1;
            }

            if ((u<<1)<=mi && !flag[u<<1]){
                flag[u<<1] = 1;
                c[u<<1]++;
                s[u<<1] += tim + 1;
                q[tail].n = u<<1;
                q[tail++].t = tim+1;
            }

        }

        //sort(v[i].begin(),v[i].end(),cmp2);
//        for (int j=0;j<10;j++)
//            printf("%d ",v[i][j].n);
//        cout << endl;
    }

}



int bisearch(int in,int k){
    int L = 0;
    int R = v[in].size();

    while(L<R){
        int mid = (L + R)/2;
        if (v[in][mid].n > k)
            R = mid;
        else
            L = mid+1;
    }

   // cout << v[in][L-1] << "<<<< " << k << endl;

    if (v[in][L-1].n != k){
        return -1;
    }
    return L-1;
}

bool ok(int x){
    for (int i=1;i<=n;i++){
        if ((temp[i]=bisearch(i,x))==-1){
            return false;
        }

    }
    return true;
}

int get(int x){
    int num = 0;
    for (int i=1;i<=n;i++){
        num += v[i][temp[i]].t;

    }
    return num;
}


void solve(){
    int mx = 1e8;
    int num = 0;
    int u;
//    for (int i=0;i<v[1].size();i++){
//        //cout << v[1][i] << " == " << ok(v[1][i]) << endl;
//        if (ok(v[1][i].n)){
//            num = get(v[1][i].n);
//
//            if (num<mx){
//                u = v[1][i].n;
//                mx = num;
//            }
//        }
//    }
    //cout << u << "  == " << endl;
    for (int i=1;i<=maxn;i++)
        if (c[i]==n){
            mx = min(mx,s[i]);
        }
    printf("%d\n",mx);
}


int main(){
    freopen("1.txt","r",stdin);
    while(scanf("%d",&n)!=EOF){
        input();
        solve();
    }
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值