8-27 2011noip初赛

在这里插入图片描述
最少:完全二叉树
为floor ( l o g 2011 + 1 ) (log^{2011}+1) (log2011+1)=12
在这里插入图片描述
找到第一个比自己高的 插入该元素后
为插入排序
在这里插入图片描述每四个二进制位转成一个十六进制位
则100位二进制位为25个十六进制位
在这里插入图片描述

双链表通过lr两个指针指向左右元素
最长遍历一次也就是k
在这里插入图片描述搜索与回溯
当当步不成立时
则还原现场重新选择
在这里插入图片描述

#include <iostream>
#include <string>
using namespace std;
const int SIZE = 200;
struct hugeint {
  int len, num[SIZE];
};
//其中 len 表示大整数的位数;num[1]表示个位、num[2]表示十位,以此类推
hugeint times(hugeint a, hugeint b) {
    //计算大整数 a 和 b 的乘积
    int i, j; hugeint ans;
    memset(ans.num, 0, sizeof(ans.num));
    for (i = 1; i <= a.len; i++)
        for (j = 1; j <= b.len; j++)+= a.num[i] * b.num[j];
    for (i = 1; i <= a.len + b.len; i++) {
        ans.num[i + 1] += ans.num[i] / 10;;
    }
    if (ans.num[a.len + b.len] > 0)
        ans.len = a.len + b.len;
    else
        ans.len = a.len + b.len - 1;
    return ans;
}
hugeint add(hugeint a, hugeint b){
    //计算大整数 a 和 b 的和
    int i; hugeint ans;
    memset(ans.num, 0, sizeof(ans.num));
    if (a.len > b.len)
        ans.len = a.len;
    else
        ans.len = b.len;
    for (i = 1; i <= ans.len; i++) {
        ans.num[i] +=;
        ans.num[i + 1] += ans.num[i] / 10;
        ans.num[i] %= 10;
    }
    if (ans.num[ans.len + 1] > 0) ans.len++;
    return ans;
}
hugeint average(hugeint a, hugeint b){
    //计算大整数 a 和 b 的平均数的整数部分
    int i; hugeint ans;
    ans= add(a, b);
    for(i = ans.len; i >= 2; i--) {
        ans.num[i  - 1] += () * 10;
        ans.num[i] /= 2;
    }
    ans.num[1] /= 2;
    if (ans.num[ans.len] == 0) ans.len--;
    return ans;
}
hugeint plustwo(hugeint a) {
    //计算大整数 a 加 2 后的结果
    int i; hugeint ans;
    ans = a;
    ans.num[1] += 2;
    i = 1;
    While ((i <= ans.len) && (ans.num[i] >= 10)) {
        ans.num[i + 1] += ans.num[i] / 10;
        ans.num[i] %= 10;
        i++;
    }
    if (ans.num[ans.len + 1] > 0);
    return ans;
}
bool over(hugeint a, hugeint b){
//若大整数 a>b 则返回 true,否则返回 false
    int i;
    if () return false;
    if (a.len > b.len) return true;
    for (i = a.len; i >= 1; i--) {
        if (a.num[i] < b.num[i])return false;
        if (a.num[i] > b.num[i]) return true;
    }
    return false;
}
int main(){
    string s;
    int i;
    hugeint target, left, middle, right;
    cin>>s;
    memset(target.num, 0, sizeof(target.num));
    target.len = s.length();
    for (i = 1; i <= target.len; i++)
        target.num[i]= s[target.len  - i] -;
    memset(left.num, 0, sizeof(left.num));
    left.len = 1;
    left.num[1] = 1;
    right = target;
    do {
        middle = average(left, right);
        if (over())right = middle;
        else left = middle;
    } while (!over(plustwo(left), right));
    for (i = left.len; i >= 1; i--)
        cout<<left.num[i];
    cout<<endl;
    return 0;
}

1.乘积的计算是将被乘数的第i位与乘数的第j位相乘 i + j - 1。 ans.num[i + j - 1]
2进位后将每一位对10取模 ans.num[i] %= 10
3.计算ans.num每一位 a.num[i] + b.num[i]
4.将每一位/2 ans.num[i] % 2
5.当num溢出时,len++ ans.len++
6.若大整数 a>b 则返回 true,否则返回 false a.len<b.len
7.将每一位符号转化为数字 ‘0’
8.二分查找求结果 times(middle, middle), target

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值