二进制表示法中1的个数最多的整数 构造

1的个数最多的整数

给定整数a和b(0≤a≤b≤263-1),输出区间[a,b]中对应二进制表示含1的个数最多的整数,如果存在多个解,则输出符合条件的最小的整数。

输入格式:

第1行:一个整数T(1≤T≤10000)为问题数。

第2~T+1行:每个问题占一行,每行输入两个整数a和b(0≤a≤b≤263-1)。数据之间用一个空格分隔。

 

输出格式:

对于每个问题,输出一行问题的编号(0开始编号,格式:case #0: 等)。然后对应每个问题在一行中输出结果。

 

Sample Input

3

0 14

100 1000

39668697550916990934597827455649079876

 

 

Sample Output

case#0:

7

case#1:

511

case#2:

4035225266123964415

 

Hints:

第一个样例数据:a=0,b=14,在[0,14]之间含1最多的整数为7(0111),11(1011),13(1101),14(1110),输出最小的整数为7.


假设有两个数(二进制表示)为

110110(较大数)

110010(较小数)

我们从最高位开始逐位比较,记录第一个不同的数字的位置pos,这里是第4个数字不同。

那么输出的答案就是  较大数字的第 1 位到第 pos - 1 位 + 0 + 1111......(后面全部都是1)

也就是 110 0 11

注意:如果较大数字从 pos 位往后全是 1 的话,答案就直接是较大数字。也就是下面这种情况:

110111(较大数)

110010(较小数)

答案11

#include <set>
#include <list>
#include <cmath>
#include <queue>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
#define MAX_N 100

using namespace std;

typedef long long int ll;

void ChangeToBinary(ll x, int a[MAX_N])
{
    int k = 0;
    while (x)
    {
        a[k++] = x % 2;
        x /= 2;
    }
}

ll ChangeToNum(int a[MAX_N])
{
    ll ret = 0;
    for (int i = 0; i < 64; i++)
        ret += a[i] * (ll)(pow(2, i) + 0.5);
    return ret;
}

int main()
{
    //freopen("in.txt", "r", stdin);
    //freopen("out.txt", "w", stdout);

    int T, Case = 0;
    cin >> T;
    while (T--)
    {
        ll a, b;
        int aa[MAX_N] = {0}, bb[MAX_N] = {0};
        scanf("%lld%lld", &a, &b);
        if (a > b)
            swap(a, b);
        ChangeToBinary(a, aa);
        ChangeToBinary(b, bb);

        int i = 63;
        while (bb[i] == aa[i])
            i--;

        int flag = 1;
        for (int j = i; j >= 0; j--)
        {
            if (!bb[j])
            {
                flag = 0;
                break;
            }
        }

        if (!flag)
        {
            bb[i] = 0;
            for (int j = i - 1; j >= 0; j--)
                bb[j] = 1;
        }
        printf("case #%d:\n%lld\n", Case++, ChangeToNum(bb));
    }
    return 0;
}




以下是实现哈夫曼树的完整可运行代码,符合要求: ```c++ #include <iostream> #include <vector> #include <queue> #include <unordered_map> #include <algorithm> using namespace std; // 哈夫曼树结点 struct TreeNode { int val; // 结点权值 int parent, left, right; // 双亲、左右孩子 TreeNode(int v = 0, int p = -1, int l = -1, int r = -1) : val(v), parent(p), left(l), right(r) {} }; // 比较器:按照结点权值从小到大排序 struct cmp { bool operator()(const TreeNode& a, const TreeNode& b) { return a.val > b.val; } }; // 构建哈夫曼树 void buildHuffmanTree(vector<TreeNode>& nodes) { priority_queue<TreeNode, vector<TreeNode>, cmp> q; // 小根堆 for (int i = 0; i < nodes.size(); i++) { q.push(nodes[i]); // 将所有结点加入堆 } while (q.size() > 1) { // 当堆元素量大于1时 TreeNode a = q.top(); // 取出堆顶元素 q.pop(); TreeNode b = q.top(); q.pop(); TreeNode c(a.val + b.val, -1, a.val < b.val ? a.parent : b.parent, a.val < b.val ? b.parent : a.parent); // 新结点的双亲为已经被选出的两个结点的双亲权值较小的那个 // 新结点的左右孩子分别为已经被选出的两个结点 nodes.push_back(c); nodes[a.parent].parent = nodes[b.parent].parent = nodes.size() - 1; // 更新已选出的结点的双亲 nodes[a.parent].val < nodes[b.parent].val ? nodes[a.parent].right = nodes.size() - 1 : nodes[b.parent].right = nodes.size() - 1; // 更新已选出的结点的右孩子 nodes[a.parent].val < nodes[b.parent].val ? nodes[b.parent].left = nodes.size() - 1 : nodes[a.parent].left = nodes.size() - 1; // 更新已选出的结点的左孩子 q.push(c); // 将新结点加入堆 } } // 求哈夫曼编码 void getHuffmanCodes(vector<TreeNode>& nodes, unordered_map<int, string>& codes) { for (int i = 0; i < nodes.size(); i++) { // 遍历所有结点 if (nodes[i].parent == -1) { // 如果是根结点 string code = ""; int j = i; while (nodes[j].parent != -1) { // 从叶子结点往上遍历到根结点 if (nodes[nodes[j].parent].left == j) { // 如果是左孩子 code = "0" + code; // 编码为0 } else { // 如果是右孩子 code = "1" + code; // 编码为1 } j = nodes[j].parent; } codes[nodes[i].val] = code; // 将编码加入哈希表 } } } // 哈夫曼编码 string huffmanEncode(string s, unordered_map<int, string>& codes) { string res = ""; for (int i = 0; i < s.size(); i++) { res += codes[s[i]]; // 将每个字符的编码拼接起来 } return res; } // 哈夫曼解码 string huffmanDecode(string s, vector<TreeNode>& nodes) { string res = ""; int j = nodes.size() - 1; // 从根结点开始遍历 for (int i = 0; i < s.size(); i++) { if (s[i] == '0') { // 如果是0,往左遍历 j = nodes[j].left; } else { // 如果是1,往右遍历 j = nodes[j].right; } if (nodes[j].left == -1 && nodes[j].right == -1) { // 如果遍历到叶子结点 res += char(nodes[j].val); // 将叶子结点的字符加入结果 j = nodes.size() - 1; // 重新从根结点开始遍历 } } return res; } int main() { int n; cout << "请输入字符的个数: "; cin >> n; vector<TreeNode> nodes(n); // 存储所有结点 cout << "请输入每个字符的权值: "; for (int i = 0; i < n; i++) { cin >> nodes[i].val; nodes[i].parent = nodes[i].left = nodes[i].right = -1; // 初始化每个结点的双亲、左右孩子 } buildHuffmanTree(nodes); // 构建哈夫曼树 unordered_map<int, string> codes; // 存储哈夫曼编码 getHuffmanCodes(nodes, codes); // 求哈夫曼编码 cout << "哈夫曼编码如下:" << endl; for (auto it = codes.begin(); it != codes.end(); it++) { cout << char(it->first) << ": " << it->second << endl; // 输出每个字符的编码 } string s; cout << "请输入要编码的字符串: "; cin >> s; string encoded = huffmanEncode(s, codes); // 哈夫曼编码 cout << "编码结果为: " << encoded << endl; string decoded = huffmanDecode(encoded, nodes); // 哈夫曼解码 cout << "解码结果为: " << decoded << endl; return 0; } ``` 注意,此代码仅为示例,实际使用时需要进行更多的错误处理和优化。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值