【机试】2011-2020年复旦大学考研复试机试真题

本文介绍了2011年至2020年复旦大学考研复试机试的部分真题,涵盖了动态规划、二叉树、栈与队列、图、查找、堆排序等算法问题,如最长公共子序列、编辑距离、汉诺塔、斐波那契数列、最大连续子序列和等,并给出了部分题目的详细描述和要求。
摘要由CSDN通过智能技术生成

一、DP问题

【2011-1】DP-最长公共子序列LCS

问题描述:输入3个子串, 输出这3个子串的最大公共子串
输入:
abcd acb abc
输出:
ab

注意:
(1)输入的字符数组以及dp数组应定义在main函数以外(全局)
(2)由于题意求的是公共字符串,而非字符串长度,因此dp数组应为string类型

#include <iostream>
#include <string.h>
#include <string>
#include <algorithm>
using namespace std;
const int maxn=35;
char a[maxn],b[maxn],c[maxn];
string dp[maxn][maxn][maxn];    //易错点
int main(){
   
	cin>>(a+1)>>(b+1)>>(c+1);
	int len1=strlen(a+1);
	int len2=strlen(b+1);
	int len3=strlen(c+1);
    //边界
	for(int i=0;i<=len1;i++){
   
		for(int j=0;j<=len2;j++){
   
			for(int k=0;k<=len3;k++){
   
			    dp[i][j][0]="";
				dp[i][0][k]="";
				dp[0][j][k]="";
			}
		}
	}
	//状态转移方程
	for(int i=1;i<=len1;i++){
   
		for(int j=1;j<=len2;j++){
   
			for(int k=1;k<=len3;k++){
   
				if(a[i]==b[j]&&a[i]==c[k]){
   
				    dp[i][j][k]=dp[i-1][j-1][k-1]+a[i];
				}else{
   
					int l1=dp[i-1][j][k].length();
					int l2=dp[i][j-1][k].length();
					int l3=dp[i][j][k-1].length();
					if(l1==max(l1,max(l2,l3))){
   
					    dp[i][j][k]=dp[i-1][j][k];
					}else if(l2==max(l1,max(l2,l3))){
   
					    dp[i][j][k]=dp[i][j-1][k];
					}else{
   
					    dp[i][j][k]=dp[i][j][k-1];
					}
				}
			}
		}
	}
    cout<<dp[len1][len2][len3]<<endl;
	return 0;
}

【2014-2】DP-字符串的编辑距离

题目描述:
把两个字符串变成相同的三个基本操作定义如下:
1.修改一个字符(如把a 变成b)
2.增加一个字符(如abed 变成abedd)
3.删除一个字符(如jackbllog 变成jackblog)
针对于jackbllog 到jackblog 只需要删除一个或增加一个l 就可以把两个字符串变为相同。
把这种操作需要的最小次数定义为两个字符串的编辑距离L。
编写程序计算指定文件中字符串的距离。输入两个长度不超过512 字节的ASCII 字符串,在
屏幕上输出字符串的编辑距离。
输入:
Hello world!
Hello word!
输出:
1

#include <iostream>
#include <string>
#include <algorithm>
using namespace std;
const int maxn=10010;
int dp[maxn][maxn];
string a,b;
int main(){
   
    getline(cin,a);
	getline(cin,b);
	int len1=a.size();
	int len2=b.size();
    //边界
	for(int i=0;i<=len1;i++){
   
	    dp[i][0]=i;
	}
	for(int j=0;j<=len2;j++){
   
	   dp[0][j]=j;
	}
	//状态转移方程
	for(int i=1;i<=len1;i++){
   
		for(int j=1;j<=len2;j++){
   
		    int flag=0;
			if(a[i-1]!=b[j-1]){
   
			    flag=1;
			}
			dp[i][j]=min(dp[i-1][j-1]+flag,min(dp[i-1][j]+1,dp[i][j-1]+1));
		}
	}
	cout<<dp[len1][len2]<<endl;
	return 0;
}

【2014-4】DP-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>
#include<math.h>
using namespace std;
int acount=1,count=0;
void hanoi(int n,char a,char b,char c){
   
	if(n==1){
   
		if((acount-count++)<=100){
   
			cout<<count<<":"<<a<<"->"<<c<<endl;
		}
	}else{
   
	    hanoi(n-1,a,c,b);
        if((acount-count++)<=100){
   
			cout<<count<<":"<<a<<"->"<<c<<endl;
		}
		hanoi(n-1,b,a,c);
	}
}
int main()
{
   
	int n;
	cin>>n;
	for(int i=0;i<n;i++){
   
	    acount*=2;
	}
	acount--;
	cout<<acount<<endl;
	hanoi(n,'A','B','C');
	return 0;
}

【2016-1】DP-求最大连续公共字串长度

题目描述:给定两个字符串,求最大公共字串的长度,长度小于1000
分为两种问题:要求计算连续最长字串的长度
如下按照寻找连续的字串理解
输入:
1111hello2222
1133hello444
输出:
5
注意:公共子串是连续的,如果求不连续,用算法笔记上P435的做法

#include <string>
#include <iostream>
#include <algorithm>
#include <cstring>
using namespace std;
const int N = 1000;
int dp[N][N] = {
   0};
int main(){
   
    string A, B;
    getline(cin, A);
    getline(cin, B);
    int l1 = A.length();
    int l2 = B.length();
    int ans = 0;
    for(int i = 0; i < l1; i++){
   
        for(int j = 0; j < l2; j++){
   
            if(A[i] != B[j]){
           //两个字符不同
                dp[i][j] = 0;
            }
            else if(i == 0 || j == 0){
        //字符相同,而且是第一个字符
                dp[i][j] = 1;
                if(ans < 1)
                    ans = 1;
            }
            else{
                             //字符相同,均不是第一个字符
                dp[i][j] = dp[i - 1][j - 1] + 1;
                if(dp[i][j] > ans){
   
                    ans = dp[i][j];
                }
            }
        }
    }
    cout << ans << endl;
    return 0;
}

【2018-3】DP-斐波那契数列

问题描述:有2n 的地板,用12和 2*1 的骨牌进行铺地板。问共有多少种情况。结果对 999983 取余,1<=n<=10000
输入:
6
输出:
13

#include<iostream>
using namespace std;
const int maxn=10010;
int dp[maxn];
int main()
{
   
	int n;
	cin>>n;
	dp[1]=1;
	dp[2]=2;
	for(int i=3;i<=n;i++){
   
	    dp[i]=dp[i-2]+dp[i-1]%999983;
	}
	cout<<dp[n]<<endl;
	return 0;
}

【2019-2】DP-最大连续子序列和

题目描述:给定一个数组及其大小,数组元素在[-106,106],元素个数最多 10^6 个。输出最大的连续子序列和,题目保证最后结果为正数。

#include <iostream>
#include <algorithm>
using namespace std;
const int maxn=1000010;
int A[maxn],dp[maxn];
int main()
{
   
	int n;
	cin>>n;
	for(int i=0;i<n;i++){
   
	    cin>>A[i];
	}
	//边界
	dp[0]=A[0];
	for(int i=1;i<n;i++){
   
		//状态转移方程
	    dp[i]=max(A[i],dp[i-1]+A[i]);
	}
	int max=0;
	for(int i=0;i<n;i++){
   
		if(dp[i]>max){
   
		    max=dp[i];
		}
	}
	if(max>0)
	    cout<<max<<endl;
	else
		cout<<"No existence"<<endl;
	return 0;
}

二、二叉树问题

【2011-2】中序与后序求层次遍历

问题描述:输入树的中序和后序排列,输出树的层次遍历
输入:
7
2 3 1 5 7 6 4
1 2 3 4 5 6 7
输出:
4 1 6 3 5 7 2

#include <stdio.h>
#include <queue>
using namespace std;
struct node{
   
    int data;
    node* lchild;
    node* rchild;
};
int n,post[35],in[35];
node* create(int postL,int postR,int inL,int inR){
          //后序和中序构造二叉树
	if(postL>postR){
                
	    return NULL;
	}
	node* root=new node;
	root->data=post[postR];
	int k;
	for(k=inL;k<=inR;k++){
   
	    if(in[k]==post[postR])
			break;
	}
	int numleft=k-inL;
	root->lchild=create(postL,postL+numleft-1,inL,k-1);
	root->rchild=create(postL+numleft,postR-1,k+1,inR);
	return root;
}
int num=0;
void LayerOrder(node* root){
        //层序遍历
    queue<node*> q;
    q.push(root);
    while(!q.empty()){
   
        node
  • 44
    点赞
  • 158
    收藏
    觉得还不错? 一键收藏
  • 6
    评论
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值