12166 - Equilibrium Mobile(DFS)

枚举每个点,判断其余深度是否存在点的权值为(1 << (deep1 - deep2)) * x

deep1,deep2为2点的深度

写的比较麻烦

#include<cstdio>
#include<vector>
#include<cstring>
#include<algorithm>
using namespace std;
typedef long long LL;
const int maxn = 1000005;
char str[maxn];
vector<LL>G[20];
LL base[20];
int  pos,cnt,max_deep;
void build(int deep){
    max_deep = max(max_deep,deep);
    if(str[pos] == '['){
        pos ++;
        build(deep + 1);
    }
    if(str[pos] >= '0' && str[pos] <= '9'){
        LL v = 0;
        while(str[pos] >= '0' && str[pos] <= '9'){
            v = v * 10 + str[pos] - '0';
            pos ++;
        }
        cnt ++;
        G[deep].push_back(v);
    }
    if(str[pos] == ']'){
        pos ++;
    }
    else if(str[pos] == ','){
        pos ++;
        build(deep);
    }
    return;
}
void solve(){
    int ret = cnt;
    for(int i = 1; i <= max_deep; i++)
        sort(G[i].begin(),G[i].end());
    for(int i = 1; i <= max_deep; i++){
        for(int j = 0; j < G[i].size(); j++){
            LL e = G[i][j];
            int ans = 0;
            for(int k = 1; k <= i; k++){
                int d = i - k;
                LL c = base[d] * e;
                int num = upper_bound(G[k].begin(),G[k].end(),c) - lower_bound(G[k].begin(),G[k].end(),c);
                ans += num;
            }
            for(int k = i + 1; k <= max_deep; k++){
                int d = k - i;
                if(e % base[d]) continue;
                LL c = e / base[d];
                int num = upper_bound(G[k].begin(),G[k].end(),c) - lower_bound(G[k].begin(),G[k].end(),c);
                ans += num;
            }
            ret = min(ret,cnt - ans);
        }
    }
    printf("%d\n",ret);
    return;
}
void init(){
    for(int i = 0; i <= 16; i++)
        G[i].clear();
    cnt = max_deep = pos = 0;
}
int main(){
    int T;
    base[0] = 1;
    for(int i = 1; i <= 16; i++)
        base[i] = base[i - 1] * 2;
    scanf("%d",&T);
    while(T--){
        init();
        scanf("%s",str);
        if(str[0] != '['){
            printf("0\n");
            continue;
        }
        build(0);
        solve();
    }
    return 0;
}
/*
2
[[3,7],6]
[[2,3],[4,5]]
[[40,40],[40,40]]
[[2,[1,1]],4]
*/


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值