B - b UVALive - 6918——位运算

本文介绍了一种利用位运算解决区间最大最小值问题的方法,通过数学归纳规律找到区间内的最大值和最小值,实现高效求解。文章提供了两种代码实现方案,包括一种因变量存储超出大小而导致错误的版本以及一种被平台接受的正确版本。
摘要由CSDN通过智能技术生成

Think:
1知识点:位运算+数学归纳规律
2思考:相信自己,决不放弃

vjudge题目链接

以下为Wrong Answer代码——变量存储超出存储大小

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <stack>

using namespace std;

typedef long long LL;

int link1[104], link2[104];
LL a[104], b[104];

void tra(int link[], int x);

int main(){
    int T, k = 1, i, j;
    LL l, r, w, sum1, sum2;
    scanf("%d", &T);
    while(T--){
        scanf("%lld %lld", &l, &r);
        tra(link1, l);
        tra(link2, r);
        for(i = 0; i < 64; i++){
            if(link1[i] == link2[i]){
                a[i] = b[i] = link1[i];
            }
            else {
                for(j = i; j < 64; j++){
                    a[j] = 1;
                    b[j] = 0;
                }
                break;
            }
        }
        sum1 = sum2 = 0, w = 1;
        for(i = 63; i >= 0; i--){
            sum1 += a[i]*w;
            sum2 += b[i]*w;
            w *= 2;
        }
        printf("Case %d: %lld %lld\n", k++, sum1, sum2);
    }
    return 0;
}
void tra(int link[], int x){
    stack <int> sta;
    while(!sta.empty()){
        sta.pop();
    }
    int i, t, l, tp = 0;
    while(x){
        t = x%2;
        sta.push(t);
        x /= 2;
    }
    l = sta.size();
    for(i = 64; i > l; i--)
        link[tp++] = 0;
    while(!sta.empty()){
        link[tp++] = sta.top();
        sta.pop();
    }
}

以下为Accepted代码

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <stack>

using namespace std;

typedef long long LL;

int link1[104], link2[104];
LL a[104], b[104];

void tra(int link[], LL x);

int main(){
    int T, k = 1, i, j;
    LL l, r, w, sum1, sum2;
    scanf("%d", &T);
    while(T--){
        scanf("%lld %lld", &l, &r);
        tra(link1, l);
        tra(link2, r);
        for(i = 0; i < 64; i++){
            if(link1[i] == link2[i]){
                a[i] = b[i] = link1[i];
            }
            else {
                for(j = i; j < 64; j++){
                    a[j] = 1;
                    b[j] = 0;
                }
                break;
            }
        }
        sum1 = sum2 = 0, w = 1;
        for(i = 63; i >= 0; i--){
            sum1 += a[i]*w;
            sum2 += b[i]*w;
            w *= 2;
        }
        printf("Case %d: %lld %lld\n", k++, sum1, sum2);
    }
    return 0;
}
void tra(int link[], LL x){
    stack <int> sta;
    while(!sta.empty()){
        sta.pop();
    }
    int i, l, tp = 0;
    LL t;
    while(x){
        t = x%2;
        sta.push(t);
        x /= 2;
    }
    l = sta.size();
    for(i = 64; i > l; i--)
        link[tp++] = 0;
    while(!sta.empty()){
        link[tp++] = sta.top();
        sta.pop();
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值