NOIP 2011 年普及组初赛试题整理

单项选择

题目答案:

C

题目解析:

摩尔 定律是由英特尔创始人之一戈登·摩尔提出来的。其内容为:当价格不变时,集成电路上可容纳的元器件的数目,约每隔 18-24 个月便会增加一倍,性能也将提升一倍。换言之,每一美元所能买到的电脑性能,将每隔 18-24 个月翻一倍以上。这一定律揭示了信息技术进步的速度。


题目答案:

C

题目解析:

只有当该二叉树为完全二叉树时,深度最小。完全二叉树的深度为  h=\left \lfloor log_{2}^{n} \right \rfloor+1


题目答案:

C

题目解析:

2^4=16,所以4位二进制可以写成1位十六进制。

100位二进制可以写成100/4=25位十六进制


问题求解

 题目答案:

3

题目解析:

1.删除 'A'

2.将 'C' 改成 'A'

3.将 'F' 改成 'C'

所以编辑距离为 3


 阅读程序

#include <iostream>
using namespace std;
int solve(int n, int m){Preferences
    int i, sum;
    if (m == 1) return 1;
    sum = 0;
    for (i = 1; i < n; i++)
        sum += solve(i, m - 1);
    return sum;
}
int main(){
    int n, m;
    cin>>n>>m;
    cout<<solve(n, m)<<endl;
    return 0;
}

输入:7 4

输出:_____

题目答案:

20

题目解析:

模拟递归调用过程,记忆每次搜索结果。

如果将 n 看作行,m 视为列,那么 solve(n,m) 求的是前n − 1行、第m − 1列所有数的和:


 

 完善程序

#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;
}

题目答案:

填空位置 ①:ans.num[i + j - 1]

填空位置 ②:ans.num[i] %= 10

填空位置 ③:a.num[i] + b.num[i]

填空位置 ④:ans.num[i] % 2

填空位置 ⑤:ans.len++

填空位置 ⑥:a.len < b.len

填空位置 ⑦:'0'

填空位置 ⑧:times(middle, middle), target

题目解析:

本题为二分 + 高精度

然后看各个函数过程的功能。可以知道 add 就是加,然后就可以很快得出 ③,注意之前有进位,它还要加上它自己。

既然这一模块唯一的空已经很快填好了,就可以不看这块了,知道这是个 a+b 的函数就行了。接下来看到 average,average 就是平均,看主过程,middle=average(left,right);这是求 a 和 b 的平均值,里面有个 ④,可以轻松看出 ④ 所在的循环是 ans 已经等于 a+b 了,现在正在除以 2。模拟笔算用的竖式除法,可以知道 ④ 这个地方是退位,就用 ans.num[i] %2就行了。

然后看到 plustwo,plustwo 的意思就是“加二”,这里面只有一个空,是 ⑤。不用看上面,只看 ⑤ 所在的 if 语句,就知道这里应该是对 ans.len 的修正,应该填ans.len++

再看到 over,在主程序里知道这是个二分用的判断函数。看到 over 中的if(a.len>b.len)这段,得知如果 a 比 b 长,也就是 a 比 b 大,那 over 就为真。看来这个 over 就是个比大小的函数,a>b 为真,a<b 为假。 ⑥ 所在的地方与下面类似,所以写上a.len<b.len

还有一个函数没看到,那就是 times,times 就是乘法,这是 a * b 的高精度乘法函数,从而可以轻易写出 ① 和 ② 。

最后主程序还有两个空,第一个空 ⑦ 是字符转数字,较简单;第二个空是在 over() 里面,而且可以发现,整个程序都没用到 times,肯定是这里用了。最后联系上下文,得出这里是 times(middle,middle),target,比较 middle 的平方与 target。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值