复旦计院2014机试真题及答案详解

A 二分查找

大家一定都能熟练掌握二分查找啦!那么来计算二分的次数吧!

约定二分的中点mid = (left + right) / 2

输入:

第一行输入一个整数NN<=10000)。

第二行输入N个升序整数。

第三行输入一个待查找的整数(必定在第二行中出现过)。

输出:

输出二分查找该整数时,进行过多少次二分。

输入样例

5

18 53 54 74 99

53

输出样例

2

#include<iostream>
#include<set>
using namespace std;

int main(){
    int n;
    cin >> n;
    int a[n];
    for(int i = 0;i < n;i++) cin >> a[i];
    int target;
    cin >> target;
    
    int low = 0,high = n - 1,count = 0;
    while(low < high){
        count++;
        int mid = low + high >> 1;
        if(a[mid] == target) break;
        if(a[mid] > target) high = mid + 1; 
        else low = mid + 1;
    }
    
    cout << count;
    
}

B 最短编辑距离

把两个字符串变成相同的三个基本操作定义如下:

1.  修改一个字符(如把变成b

2.  增加一个字符(abed  变成abedd)

3.  删除一个字符(如jackbllog  变成jackblog

针对于jackbllog jackblog  只需要删除一个或增加一个就可以把两个字符串变为相同。

把这种操作需要的最小次数定义为两个字符串的编辑距离L

编写程序计算指定文件中字符串的距离。输入两个长度不超过512 字节的ASCII 字符串,在

屏幕上输出字符串的编辑距离。

输入样例

Hello world!

Hello word!

输出样例

1

DP问题——最短编辑距离_m0_43400216的博客-CSDN博客

C 二叉树遍历

问题定义

输入一棵二叉树,输出树的前、中、后序遍历结果。

输入一个整数N(N<= 10000),表示树中有N个结点(编号0~N-1)。

接下来N行,依次为结点0~结点N-1的左右孩子情况。

每行3个整数,F,L,R。L,R为F的左右孩子。L,R如果为-1表示该位置上没有孩子。

分三行分别输出树的前中后序遍历。

同一行中的数字,用一个空格间隔。

输入样例

5

0 3 1

1 2 -1

2 -1 4

3 -1 -1

4 -1 -1

输出样例

0 3 1 2 4

3 0 2 4 1

3 4 2 1 0

#include<iostream>
#include<cstring>
using namespace std;
const int N = 10000;
int e[N],le[N],re[N];

void NLR(int x){
    cout << x << ' ';;
    if(le[x] != -1) NLR(le[x]);
    if(re[x] != -1) NLR(re[x]);
}

void LNR(int x){
    if(le[x] != -1) LNR(le[x]);
    cout << x << ' '; 
    if(re[x] != -1) LNR(re[x]);
}

void LRN(int x){
    if(le[x] != -1) LRN(le[x]);
    if(re[x] != -1) LRN(re[x]);
    cout << x << ' ';
}
int main(){
    int n;
    cin >> n;
    for(int i = 0;i < n;i++){
        int f,l,r;
        cin >> f >> l >> r;
        le[f] = l;
        re[f] = r;
    }
    
    NLR(0);
    cout << endl;
    LNR(0);
    cout << endl;
    LRN(0);
}

Hanoi

Hanoi 塔问题是印度的一个古老的传说。开天辟地的神勃拉玛在一个庙里留下了三根金刚石的棒,第一根上面套着64 个圆的金片,最大的一个在底下,其余一个比一个小,依次叠上去,庙里的众僧不倦地把它们一个个地从这根棒搬到另一根棒上,规定可利用中间的一根棒作为帮助,但每次只能搬一个,而且大的不能放在小的上面。

请编写程序,把A 柱上的n 个金片,搬动到C 柱(中间可以使用B 柱),使得搬动的次数最少。输入金片的个数n(1<=n<=64),输出总搬动次数,以及最后100 次搬动。如果搬动次数小于等于100 则全部输出;每个搬动占一行,加上是这第几次搬动的数字和”:”,格式见示例。

输入样例

2

输出样例

3

1:A->B

2:A->C

3:B->C

#include<iostream>
using namespace std;
int dp[65],current,n;
//输出
void printfs(char from,char to){
    current++;
    if(dp[n] <= 100 || dp[n] - current < 100)
        printf("%d:%c->%c\n",current,from,to); 
    return;
}
//将n个环从 x杆移动到y杆
void move1(char from,char to,char helper,int n){ //helper
    if(n == 1) {
        printfs(from,to);
        return;
    }
    // 将n-1个环从x移动到z
    move1(from,helper,to,n-1);
    //把第n个环从x移动到y
    move1(from,to,helper,1);
    //把n-1个环从z移动到y
    move1(helper,to,from,n-1);
}
int main(){
    cin >> n;
    dp[1] = 1;
    dp[2] = 3;
    for(int i = 3;i <= n;i++) 
        dp[i] = dp[i - 1] * 2 + 1; //dp[i]为将i个环从a杆移动到c杆的最少次数
        
    cout << dp[n] << endl;    
    
    move1('A','C','B',n);
    return 0;
}

dp的思想+递归函数。 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值