题型分布目录

  • 一、DP问题
    • 【2011-1】DP-最长公共子序列LCS
    • 【2014-2】DP-字符串的编辑距离
    • 【2014-4】DP-Hanoi 塔
    • 【2016-1】DP-求最大连续公共字串长度
    • 【2018-3】DP-斐波那契数列
    • 【2019-2】DP-最大连续子序列和
  • 二、二叉树问题
    • 【2011-2】中序与后序求层次遍历
    • 【2012-2】二叉树最大叶子间距
    • 【2014-3】二叉树前中后序遍历
    • 【2019-3】二叉树的形态数
  • 三、栈或队列问题
    • 【2015-3】优先队列
    • 【2016-2】后缀序列求值
    • 【2016-3】字符串的哈夫曼编码最短长度
  • 四、图
    • 【2013-3】图的BFS遍历
  • 五、查找
    • 【2014-1】二分查找
  • 六、堆排序
    • 【2012-1】1000名求前30%
  • 七、基础题(水题)
    • 【2012-3】字符串的重复输出
    • 【2013-1】字符串匹配
    • 【2013-2】A Famous ICPC Team
    • 【2015-1】长方形中的正方形
    • 【2015-2】a与b得到c
    • 【2016-1】求最大公共字串长度
    • 【2017-1】中位数
    • 【2017-2】9位ISBN,求其校验位
    • 【2018-1】求众数
    • 【2018-2】解一元一次方程
    • 【2019-1】日期处理
  • 八、补充2020年机试题
    • A、斗牛
    • B、打地鼠
    • C、排队打饭
    • D、二叉搜索树
    • E、序列

一、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;elsecout<<"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* now=q.front();q.pop();printf("%d",now->data);     num++;if(num<n)printf(" ");if(now->lchild!=NULL){q.push(now->lchild);}if(now->rchild!=NULL){q.push(now->rchild);}}
}
int main(){scanf("%d",&n);for(int i=0;i<n;i++){scanf("%d",&post[i]);}for(int i=0;i<n;i++){scanf("%d",&in[i]);}node* root=create(0,n-1,0,n-1);LayerOrder(root);printf("\n");return 0;
}

【2012-2】二叉树最大叶子间距

问题描述:二叉树问题。比如节点是ABCDE编号是01234,给出每个左右子树的编号。求最大叶子间距。
输入1:
3
1 2
-1 -1
-1 -1
输出1:
2
输入2:
6
1 -1
2 3
4 -1
-1 5
-1 -1
-1 -1
输出2:
4

#include <stdio.h>
const int maxn=100;
struct node{int lchild,rchild;
}Node[maxn];
int maxd;  //全局变量记录最大叶子间距
//求最大叶子间距
int maxDistance(int root,int &maxd){if(root==-1)return -1;int lefth=maxDistance(Node[root].lchild,maxd)+1;int righth=maxDistance(Node[root].rchild,maxd)+1;if(lefth+righth>maxd){maxd=lefth+righth;}return lefth>righth?lefth:righth;   //返回的是当前结点为根时的深度
}
int main(){int n,left,right;scanf("%d",&n);for(int i=0;i<n;i++){scanf("%d %d",&left,&right);Node[i].lchild=left;Node[i].rchild=right;}maxDistance(0,maxd);printf("%d\n",maxd);return 0;
}

【2014-3】二叉树前中后序遍历

题目描述:
输入一棵二叉树,输出树的前、中、后序遍历结果。
输入一个整数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 <stdio.h>
const int maxn=10010;
struct node{int lchild,rchild;
}Node[maxn];
int n,num=0;
bool flag[maxn]={false};
void print(int id){printf("%d",id);num++;if(num<n)printf(" ");elseprintf("\n");
}
void preOrder(int root){if(root==-1)return;print(root);preOrder(Node[root].lchild);preOrder(Node[root].rchild);
}
void inOrder(int root){if(root==-1)return;inOrder(Node[root].lchild);print(root);inOrder(Node[root].rchild);
}
void postOrder(int root){if(root==-1)return;postOrder(Node[root].lchild);postOrder(Node[root].rchild);print(root);
}
int main(){int x,left,right;scanf("%d",&n);for(int i=0;i<n;i++){scanf("%d%d%d",&x,&left,&right);Node[x].lchild=left;Node[x].rchild=right;flag[left]=true;flag[right]=true;}int root;for(int i=0;i<n;i++){if(flag[i]==false){root=i;}}preOrder(root);num=0;inOrder(root);num=0;postOrder(root);return 0;
}

【2019-3】二叉树的形态数

题目描述:给定二叉树的节点总数 n,输出二叉树形态总数,n<= 1000
输入:
3
输出:
5

#include <stdio.h>
long long function(int n){    //防止阶乘的结果溢出,使用long long型long long res;if(n==0)res=0;else if(n==1)res=1;else{res=n;while(n>1){res=res*(n-1);n--;}}return res;
}
int main(){int n;long long result;scanf("%d",&n);result=function(2*n)/function(n)/function(n+1);printf("%lld\n",result);return 0;
}

三、栈或队列问题

【2015-3】优先队列

题目描述:给出优先队列的实现,实现4个操作

• ADD(N,P):往队列里加入id为N的优先级为P的任务
• NEXT:输出下一个最高优先级的任务的id,如果优先级相同输出id小的任务,若队列中没有任务输出-1
• REMOVE(N):移除id为N的任务
• COUNT:输出队列中的任务数量

#include <stdio.h>
#include <iostream>
#include <vector>
#include <queue>
#include <string>
using namespace std;
struct node{ int id;  int p;   //优先级
};
struct cmp{bool operator()(node a,node b){if(a.p!=b.p)return a.p<b.p;elsereturn a.id>b.id;}
};
priority_queue<node,vector<node>,cmp> q;
priority_queue<node,vector<node>,cmp> temp;  //临时优先队列
void add(int id,int p){node a;a.id=id;a.p=p;q.push(a);
}
void next(){node a;a=q.top();cout<<a.id<<" "<<a.p;
}
void remove(int id){node a=q.top();while(a.id!=id){node b=a;q.pop();temp.push(b);}
}
int main(){int id,p;string str;cin>>str;while(1){if(str=='ADD'){scanf("%d%d",&id,&p);add(id,p);}else if(str=='NEXT'){next();}else if(str=='REMOVE'){scanf("%d",&id);remove(id);}else if(str=='COUNT'){int num=q.size();cout<<num<<endl;}else break;}return 0;
}

【2016-2】后缀序列求值

题目描述:
给定一个后缀序列,要求求值,只有加减
输入:
123++4-
输出:
2

#include <iostream>
#include <stack>
#include <string>
using namespace std;
stack<int> s;
int main(){string str;cin>>str;int k;for(int i=0;i<str.size();i++){if(str[i]>='0'&&str[i]<='9'){int temp=str[i]-'0';s.push(temp);}else if(str[i]=='+'){int a=s.top();s.pop();int b=s.top();s.pop();k=b+a;s.push(k);}else if(str[i]=='-'){int a=s.top();s.pop();int b=s.top();s.pop();k=b-a;s.push(k);}}cout<<s.top()<<endl;return 0;
}

【2016-3】字符串的哈夫曼编码最短长度

题目描述:给定一个字符串(长度不超过100),求哈夫曼编码的最短长度。
输入1:
abbcccdddd
输出1:
19
输入2:
we will we will r u
输出2:
50
主要思想:优先队列+map数组+栈

#include <iostream>
#include <map>
#include <vector>
#include <queue>
#include <string>
using namespace std;
map<char,int> mp;
priority_queue<int,vector<int>,greater<int>> q;
string str;
int main(){getline(cin,str);int len=str.length();for(int i=0;i<len;i++){if(mp.find(str[i])==mp.end()){mp[str[i]]=1;}elsemp[str[i]]++;}for(map<char,int>::iterator it=mp.begin();it!=mp.end();it++){q.push(it->second);}int ans=0;while(q.size()!=1){int temp;int a=q.top();q.pop();int b=q.top();q.pop();temp=b+a;ans+=temp;q.push(temp);}cout<<ans<<endl;return 0;
}

四、图

【2013-3】图的BFS遍历

题目描述:给一个表,问两个位置之间的最短距离是多少,其中素数位置不能经过。
输入:
3
1 4
9 32
10 12
输出:
Case 1: 1
Case 2: 7
Case 3: impossible

#include <iostream>
#include <string>
#include <cstring>
#include <cctype>
#include <cstdio>
#include <map>
#include <stack>
#include <cmath>
#include <queue>
#include <algorithm>
#define UP 0
#define DOWN 1
#define LEFT 2
#define RIGHT 3
using namespace std;
const int maxn=410;
int g[maxn][maxn];
int vis[maxn][maxn];
const int mov[4][2]= {{-1,0},{1,0},{0,-1},{0,1}};
bool isPrime(int v)
{int ed=sqrt(v);for(int i=2; i<=ed; ++i)if(v%i==0) return false;return true;
}
int nextDir(int d)
{if(d==RIGHT) return UP;else if(d==UP) return LEFT;else if(d==LEFT) return DOWN;else if(d==DOWN) return RIGHT;
}
pair<int,int> pos[10005];
void init()
{int val=0;int x=200,y=200;g[x][y]=++val;pos[val]=make_pair(x,y);int d=RIGHT;int len=2;while(len<=105){for(int i=1; i<len; ++i){x=x+mov[d][0];y=y+mov[d][1];++val;if(isPrime(val)) g[x][y]=0;else{g[x][y]=val;if(val<=10000)pos[val]=make_pair(x,y);}}d=nextDir(d);for(int i=1; i<len; ++i){x=x+mov[d][0];y=y+mov[d][1];++val;if(isPrime(val)) g[x][y]=0;else{g[x][y]=val;if(val<=10000)pos[val]=make_pair(x,y);}}d=nextDir(d);++len;}}int bfs(int st,int ed)
{memset(vis,0,sizeof(vis));queue<pair<int,int> > que;que.push(pos[st]);while(!que.empty()){pair<int,int> p=que.front();que.pop();for(int i=0; i<4; ++i){int nx=p.first+mov[i][0],ny=p.second+mov[i][1];if(vis[nx][ny]||g[nx][ny]==0) continue;vis[nx][ny]=vis[p.first][p.second]+1;if(g[nx][ny]==ed) return vis[nx][ny];que.push(make_pair(nx,ny));}}return -1;
}
int main()
{init();int x,y,kase=0;while(scanf("%d%d",&x,&y)!=EOF){printf("Case %d: ",++kase);if(x==y) printf("0\n");else{int ans=bfs(x,y);if(ans==-1) puts("impossible");else printf("%d\n",ans);}}return 0;
}

五、查找

【2014-1】二分查找

题目描述:大家一定都能熟练掌握二分查找啦!那么来计算二分的次数吧!约定二分的中点mid = (left + right) / 2。
输入
第一行输入一个整数N(N<=10000)。
第二行输入N个升序整数。
第三行输入一个待查找的整数(必定在第二行中出现过)。
输出
输出二分查找该整数时,进行过多少次二分。
输入:
5
18 53 54 74 99
53
输出:
2

#include<iostream>
#include<stdio.h>
using namespace std;
int count=0,input[10001];
void search(int s,int e,int key)
{count++;int mid=(s+e)/2;if(input[mid]==key) return;else if(input[mid]>key) search(s,mid,key);else search(mid,e,key);
}
int main()
{freopen("p1.in","r",stdin);freopen("p1.out","w",stdout);int N,key;cin>>N;for(int i=0;i<N;i++) cin>>input[i];cin>>key;search(0,N-1,key);cout<<count<<endl;fclose(stdin);fclose(stdout);return 0;
}

六、堆排序

【2012-1】1000名求前30%

问题描述:排序问题:1000个成绩输出前30%。
我这里输入十组数据,输出前3个
思路:
采用堆排序最佳。

#include <cstdio>
#include <algorithm>
using namespace std;//给定十个元素输出最大的前三个,元素从下标1开始存储
int heap[11] = {0, 3, 1, 2, 6, 5, 4, 9, 8, 7, 10};
int n = 10;      //元素个数//对heqap数组在loe和high范围内进行调整
//low为父节点,high一般为堆的最后一个元素下标
void downAdjust(int low, int high){int i = low, j = i * 2;     //i为调整节点,j为左孩子while(j <= high){           //如果存在左孩子if(j + 1 <= high && heap[j + 1] > heap[j]){     //如果右孩子存在,且值大于左孩子j = j + 1;          //j来存储右孩子下标}//孩子中最大的权值大于要调整的节点if(heap[j] > heap[i]){swap(heap[j], heap[i]);i = j;          //继续调整以j为父节点的子树j = i * 2;}elsebreak;}
}
//建树
void createHeap(){for(int i = n / 2; i >= 1; i--){        //i从第一个非叶节点开始,直到根结点downAdjust(i, n);}
}
void heapSort(){createHeap();   //建堆printf("%d", heap[1]);    //输出第一个最大值for(int i = n; i > 8; i--){     //倒着枚举,直到输出符合题目要求的数量swap(heap[i], heap[1]);     //交换heap[i]与堆顶downAdjust(1, i - 1);       //调整堆顶printf(" %d", heap[1]);     //调整过后,堆顶元素为最大值,输出}printf("\n");
}int main(){heapSort();return 0;
}

七、基础题(水题)

【2012-3】字符串的重复输出

题目描述:给一个字符串比如ABC 再给一个整数比如3输出AAABBBCCC就行了。

#include <string>
#include <iostream>
#include <cstdio>
using namespace std;int main(){string str;getline(cin, str);int n;cin >> n;for(int i = 0; i < str.size(); i++){for(int j = 0; j < n; j++){printf("%c", str[i]);}}printf("\n");return 0;
}

【2013-1】字符串匹配

题目描述:对于主串M和模式串P,找到P在M中出现的所有子串的第一个字符在P中的位置。P中第一个字符所在的位置为0。首行的数字表示有多少组字符串。
输入:
2
ababababa
ababa
aaa
aa
输出:
0 2 4
0 1
(相邻位置之间用一个空格隔开)

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
char str1[100],str2[100];
int main()
{int n;scanf("%d",&n);while(n--){memset(str1,0,sizeof(str1));memset(str2,0,sizeof(str2));scanf("%s",str1);scanf("%s",str2);int len1=strlen(str1);int len2=strlen(str2);int idx;for(int i=0;i<len1;i++){if(str1[i]!=str2[0])continue;idx=i;if(len1-i<len2)break;for(int j=0;j<len2;j++){if(str1[i]!=str2[j])break;i++;if(j=len2-1)printf("%d ",idx);}i=idx;}}system("pause");return 0;
}

【2013-2】A Famous ICPC Team

题目描述:给出四个正方体箱子的边长,问能装下这四个正方体箱子的大正方体边长最小要多大,要求边长最小且必须能装下四个箱子。
输入:
2
2 2 2 2
输出:
4

#include <stdio.h>
#include <string.h>
#include <algorithm>
using namespace std;
int main()
{int a[4],cas = 1;int x,y,ans;while(~scanf("%d%d%d%d",&a[0],&a[1],&a[2],&a[3])){sort(a,a+4);printf("Case %d: %d\n",cas++,a[2]+a[3]);}return 0;
}

【2015-1】长方形中的正方形

题目描述:给出长方形的长和宽,每次从长方形里撕去最大的正方形,输出最后能得到多少正方形
输入:
3 4
输出:
4

#include <cstdio>
#include <algorithm>
using namespace std;int main(){int a, b;   //a 长 , b 宽scanf("%d%d", &a, &b);int ans = 0;while(a != b){ans++;if(a < b){swap(a, b);}a = a - b;}printf("%d", ans + 1);return 0;
}

【2015-2】a与b得到c

题目描述:给出a,b,c(3个整数),判断a,b能否通过±*/得到c,ab可以交换位置,可以输出YES,不行输出NO
输入:
3 8 2
输出:
NO

#include <cstdio>
int main(){long long a, b, c;scanf("%lld%lld%lld", &a, &b, &c);if(a + b == c || a * b == c){printf("YES\n");}else if(a - b == c || b - a == c){printf("YES\n");}else if(a / b == c  || b / a == c){printf("YES\n");}else{printf("NO\n");}return 0;
}

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

题目描述:给定两个字符串,求最大公共字串的长度,长度小于1000
分为两种问题:要求计算连续最长字串的长度
如下按照寻找连续的字串理解
输入:
1111hello2222
1133hello444
输出:
5

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

【2017-1】中位数

题目描述:给定一个整数序列,求中位数。如果序列个数为奇数,中位数为升序的中间位置,如果是偶数,这位升序的中间两个数的平均值。
输入
输入包含多组测试数据,每一组第一行为n(n<104)表示这个序列的个数,接下来有n个整数k(0<k<231-1)
输出
输出这个序列的中位数
输入1:
5
2 1 4 3 5
输出1:
3
输入2:
4
1 4 3 2
输出2:
3

#include <cstdio>
#include <algorithm>
using namespace std;
const int N = 10010;
int num[N];int main(){int n;scanf("%d", &n);for(int i =  0; i < n; i++){scanf("%d", &num[i]);}sort(num, num + n);if(n % 2 == 0){     //n为偶数if((num[n / 2] + num[n / 2 - 1]) % 2 == 0){     //中间两位平均值为整数printf("%d\n", (num[n / 2] + num[n / 2 - 1]) / 2);}else{printf("%.lf\n", (num[n / 2] + num[n / 2 - 1]) / 2.0);}}else{       //n为奇数printf("%d\n", num[n / 2]);}return 0;
}

【2017-2】9位ISBN,求其校验位

题目描述:给定一个9位数字的ISBN,求其校验位。ISBN格式为2-02-033598,校验位的计算方法如下:从左到右依次将各位数字乘10,9,8,……,2,求出其和S,作模运算得M=S mod 11。若11-M在1和9之间,校验位即为该数字;若11-M等于10,校验位为X;11-M等于11,校验位为0。输出添加校验位的ISBN,如2-02-033598-0。
输入1:
2-02-033598
输出1:
2-02-033598-0
输入2:
7-309-04547
输出2:
7-309-04547-5

#include <cstdio>
#include <cstring>
char str[15];
int a[10];int main(){scanf("%s", str);int count = 0;for(int i = 0; i < 11; i++){if(str[i] != '-'){a[count++] = str[i] - '0';}}int s = 0;int d = 10;for(int i = 0; i < 9; i++){s += a[i] * d;--d;}int m = s % 11;int t = 11 - m;if(t < 10){printf("%s-%d\n", str, t);}else if(t == 10){printf("%s-X\n", str);}else{printf("%s-0\n", str);}return 0;
}

【2018-1】求众数

题目描述:众数就是一个序列中出现次数最多的数字。 如果不唯一,则输出小的那个值。
样例输入:
第一行给出N(1<=n<=10^5 ),第二行给出N个数字,每个数字在int范围内
输入1:
8
10 3 8 8 3 2 2 2
输出1:
2
输入2:
5
3 3 2 4 2
输出2:
2

#include <cstdio>
#include <map>
#include <algorithm>
using namespace std;
map<int, int> mp;int main(){int n, x;int maxn = 0;int maxp;scanf("%d", &n);for(int i = 0; i < n; i++){scanf("%d", &x);if(mp.find(x) != mp.end()){     //这个数已经出现过mp[x]++;}else{mp[x] = 1;}}for(map<int, int>::iterator it = mp.begin(); it != mp.end(); it++){if(it->second > maxn){      //已经从小到大排好序,取>即可maxn = it->second;      //众数出现的次数maxp = it->first;       //众数的值}}printf("%d", maxp);

【2018-2】解一元一次方程

题目描述:解方程,给定一个字符串,代表一个一元一次方程。如果有解求解,输出格式“x=数字“,如果解的个数无穷,输出 “infinite solutions”。如果没有解输出“no solution”,字符串长度不超过 256 。
输入:
2x+4-3x=x-2
输出:
x=2

#include <cstdio>
#include <iostream>
#include <string>
using namespace std;
string str;int main(){cin >> str;int a = 0, b = 0;   //系数、常数int sym = 1, flag = 1;      //sym表示数字之前的符号,flag表示等号的左右(初始值为1,表示在左面)int i = 0;          //访问字符串的下标while(i < str.size()){if(str[i] == '='){sym = 1;flag = -1;}else if(str[i] == '+'){sym = 1;}else if(str[i] == '-'){sym = -1;}else{       //遇到数字或者xint t = 0;      //暂存遇到的数字值while(i < str.size() && str[i] >= '0' && str[i] <= '9'){    //遇到数字,计算数值t = 10 * t + (str[i] - '0');++i;}//当表达式最后一位是数字时,比如2x+4-3x=x-2,上面while的循环会使i >= str.size()成立if(i >= str.size()){                b -= t * sym;break;}if(str[i] == 'x' && t == 0){        //如果x之前的系数为正负1时,要单独判断,因为此时t=0a += sym * flag;}else if(str[i] == 'x'){     //处理系数a += t * sym * flag;}else{                       //处理常数b += t * sym * flag;continue;               //直接进行下一次循环是因为:上面while循环中处理数字之后已经++i}}i++;}if(a == 0 && b == 0){printf("infinite solutions\n");}else if(a != 0 && b % a == 0){printf("x=%d\n", -b/a);}else{printf("no solution\n");}return 0;
}

【2019-1】日期处理

题目描述:输入日期格式:YYYYMMDD,求与20190205的相隔的天数。
输入:20190208
输出:3

#include <cstdio>
#include <iostream>
#include <algorithm>
using namespace std;//month[2][0]平年, month[2][1]闰年
int month[13][2] = {{0,0}, {31, 31}, {28,29}, {31,31}, {30,30}, {31, 31}, {30,30},{31, 31}, {31, 31}, {30,30}, {31, 31},{30,30},{31, 31}} ;bool isLeapYear(int year){if(year % 400 == 0 || (year % 4 == 0  && year % 100 != 0)){return true;}return false;
}int main(){int time1, time2 = 20190205;scanf("%d", &time1);if(time1 > time2){swap(time1, time2);}int y1, m1, d1, y2, m2, d2;y1 = time1 / 10000, m1 = time1 % 10000 / 100, d1 = time1 % 100;y2 = time2 / 10000, m2 = time2 % 10000 / 100, d2 = time2 % 100;int num = 0;while(y1 < y2 || m1 < m2 || d1 < d2){d1++;num++;if(d1 == month[m1][isLeapYear(y1)] + 1){m1++;d1 = 1;}if(m1 == 13){y1++;m1 = 1;}}cout << num << endl;return 0;
}

八、补充2020年机试题

A、斗牛

题目描述:给定五个 0~9 范围内的整数 a1, a2, a3, a4, a5。如果能从五个整数中选出三个并且这三个整数的和为10 的倍数(包括 0),那么这五个整数的权值即为剩下两个没被选出来的整数的和对 10 取余的结果,显然如果有多个三元组满⾜和是 10 的倍数,剩下两个数之和对 10 取余的结果都是相同的;如果
选不出这样三个整数,则这五个整数的权值为 -1。
现在给定 T 组数据,每组数据包含五个 0~9 范围内的整数,分别求这 T 组数据中五个整数的权值。
【输入格式】 第一行一个整数 T (1<=T<=1000),表⽰数据组数。 接下来 T 行,每行 5 个 0~9 的整数,表示一组数据。
【输出格式】输出 T 行,每行一个整数,表⽰每组数据中五个整数的权值。

#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;//回溯法得到其中三数之和,若没有10的倍数,返回-1
int judge(int sum,vector<int>& visited,vector<int>D,int num) {if (num > 3)   return -1;if (num == 3 && sum % 10 == 0)    return sum;for (int i = 0; i < D.size(); i++) {if (visited[i] == 0) {visited[i] = 1;int f = judge(sum + D[i], visited, D, num + 1);if (f != -1)    return f;visited[i] = 0;}}return -1;
}int main()
{int T;cin >> T;int N = 5;vector<vector<int>>data(T, vector<int>(N));for (int i = 0; i < T; i++) {for (int j = 0; j < N; j++) {cin >> data[i][j];}}vector<int>result;vector<int> visited(N, 0);  //记录已被访问过的数for (int i = 0; i < T; i++) {int sum = 0, num = 0;fill(visited.begin(), visited.end(), 0);int flag = judge(sum, visited, data[i], num);if (flag != -1) {   //存在三数之和为10的倍数int S = 0;for (int j = 0; j < N; j++)  S += data[i][j];result.push_back((S - flag) % 10);    //总和减去三数之和就是剩余两数之和}else  result.push_back(flag);}for (int i = 0; i < result.size(); i++)  cout << result[i] << endl;
}

B、打地鼠

题目描述:给定 n 个整数 a1, a2, …, an 和⼀个 d,你需要选出若⼲个整数,使得将这些整数从⼩到⼤排好序之后,任意两个相邻的数之差都不⼩于给定的 d,问最多能选多少个数出来。
【输⼊格式】 第⼀⾏两个整数 n,d (1<=n<=10^5, 0<=d<=10^9),分别表⽰整数个数和相邻整数差的下界。 第⼆⾏ n
个整数 a1, a2, …, an (1<=ai<=10^9, 1<=i<=n),表⽰给定的 n 个整数。
【输出格式】 仅⼀⾏⼀个整数,表⽰答案。

#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int main()
{int n, d;cin >> n >> d;vector<int>data(n);for (int i = 0; i < data.size(); i++)    cin >> data[i];sort(data.begin(), data.end());    //从小到大排序int num = 0;if (n < 2) {    //只有一个整数cout << num << endl;return 0;}for (int i = 0, j = 1; j < data.size();) {if (data[j] - data[i] >= d) {num++;i = j;j++;}else j++;}if (num == 0) cout << num << endl;    //没有符合条件的数else  cout << num + 1 << endl;   //由于每次只将较小的数加入结果集,因此最后还需将最后的大数加入结果集return 0;
}

C、排队打饭

题目描述:下课了,有 n 位同学陆续赶到⻝堂进⾏排队打饭,其中第 i 位同学的到达时间为 ai,打饭耗时为 ti,等待时间上限为 bi,即如果其在第 ai+bi 秒的时刻仍然没有轮到他开始打饭,那么他将离开打饭队列,另寻吃饭的地⽅。问每位同学的开始打饭时间,或者指出其提前离开了队伍(如果这样则输出 -1)。
【输⼊格式】 第一行一个整数 n (1<=n<=105),表⽰来打饭的同学数量。 接下来 n行,每⾏三个整数 ai,ti,bi (1<=ai,ti,bi<=10^9, 1<=i<=n),分别表⽰每位同学的到达时间、打 饭耗时、等待时间上限。 保证 a1<a2<…<an
【输出格式】 一行n 个整数,表⽰每位同学的开始打饭时间或者 -1(如果该同学提前离开了队伍)。

#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int main()
{int n;cin >> n;vector<vector<long long int>>data(n, vector<long long int>(3));for (int i = 0; i < data.size(); i++){for (int j = 0; j < data[i].size(); j++) {cin >> data[i][j];}}long long int endtime = 0;    //记录上一个学生打饭结束的时间vector<long long int>result;for (int i = 0; i < data.size(); i++) {if (data[i][0] >= endtime) { //第i位学生达到时无人打饭,可以直接开始打饭result.push_back(data[i][0]);endtime = data[i][0] + data[i][1];}else {  //第i位学生正好有人打饭,那么第i位学生的等待时间=上一位学生的结束时间-第i位学生的开始时间if (endtime - data[i][0] > data[i][2])  result.push_back(-1);   else {result.push_back(endtime);endtime = endtime + data[i][1];}}}for (int i = 0; i < result.size(); i++)   cout << result[i] << ' ';return 0;
}

D、二叉搜索树

题目描述:给定⼀个 1-n 的排列 P,即⻓度为 n,且 1~n 中所有数字都恰好出现⼀次的序列。现在按顺序将排列中的元素⼀⼀插⼊到初始为空的⼆叉搜索树中(左小右大),问最后每个节点的⽗亲节点的元素是什么。特别地,根节点的⽗亲节点元素视为 0。
【输⼊格式】
第⼀⾏⼀个整数 n (1<=n<=10^5),表⽰排列 P 中的元素个数。
第⼆⾏ n 个整数 p1, p2, …, pn (1<=pi<=n, 1<=i<=n),表⽰给定的排列。
【输出格式】 ⼀⾏ n 个整数,其中第 i 个整数 ai 表⽰元素 i 对应节点的⽗亲节点的元素。特别地,根节点的⽗亲节 点元素视为 0。

#include <iostream>
#include <vector>
#include <map>
#include <algorithm>
using namespace std;
int main(){int n;cin >> n;vector<int>father(n + 1);map<int, int>dict;dict[0] = 0;int maxn = 0;for (int i = 0; i < n; i++) {int t;cin >> t;if (t > maxn) {father[t] = maxn;dict[t] = dict[maxn] + 1;maxn = t;}else {map<int, int>::iterator small = dict.upper_bound(t);map<int, int>::iterator big = small--;if (big->second > small->second) {father[t] = big->first;dict[t] = big->second + 1;}else {father[t] = small->first;dict[t] = small->second + 1;}}}for (int i = 1; i < father.size(); i++)  cout << father[i] << ' ';
}

E、序列

题目描述:给定⼀个⻓为 n 的序列 A,其中序列中的元素都是 0~9 之间的整数,对于⼀个⻓度同样为 n 整数序列B,定义其权值为 |A_i-B_i| (1<=i<=n) 之和加上 (B_j-B_j+1)^2 (1<=j<n) 之和。求所有⻓为 n 的整数序列中,权值最⼩的序列的权值是多少。
【输⼊格式】 第⼀⾏⼀个整数 n (1<=n<=10^5),表⽰序列 A 的⻓度。 第⼆⾏ n 个整数 a1, a2, …, an (0<=ai<=9, 1<=i<=n),表⽰序列 A 中的元素。
【输出格式】仅⼀⾏⼀个整数,表⽰答案。

#include <iostream>
#include <vector>
#include <algorithm>
#include <climits>
#include <math.h>
using namespace std;#define N 10int main() {int n;cin >> n;vector<int>A(n);for (int i = 0; i < A.size(); i++) cin >> A[i];vector<vector<int>>dp(n, vector<int>(N, INT_MAX));for (int i = 0; i < N; i++) dp[0][i] = abs(i - A[0]);for (int i = 1; i < A.size(); i++) {for (int j = 0; j < N; j++) {for (int k = 0; k < N; k++) {dp[i][j] = min(dp[i][j], dp[i - 1][k] + abs(A[i] - j) + (j - k)*(j - k));}}}int result = INT_MAX;for (int i = 0; i < N; i++)    result = min(result, dp[n - 1][i]);cout << result;return 0;
}

温馨提示:资源整理不易,看到最后,记得一键三连奥,笔芯!!!

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

  1. 2011年华科计算机考研复试机试题真题

    很好的资料哦,更多资料请访问王道论坛:www.cskaoyan.com 2011年华科计算机考研复试机试题真题:

  2. 南京大学java机试,2019年南京大学计算机考研复试机试真题

    目录 第一题 Stepping Numbers 题意 思路 代码 反思 第二题 Nodes from the Root 题意 思路 代码 大佬的标准题解代码: 菜鸡我的又费空间,又费时间,又臭又长,思 ...

  3. 计算机考研复试【面试真题】

    前言 本人为21考研,所报专业为计算机科学与技术,下面记录一下本人参加复试时被问的问题~(专业课科目为数据库原理) 1. 数据库系统的组成 2. 数据库恢复技术 3. 数据库故障有哪些 4. 最喜欢的 ...

  4. 华师大计算机在线作业,华东师范大学计算机考研复试机试习题

    华东师范大学计算机考研复试机试习题 华东师范大学计算机考研:计算机系.数据学院复试机试历年真题以及AC代码.历年学长总结得到.适用学院:计算机学院.数据学院.软件学院也可参考.sum/=10;prin ...

  5. 华科计算机考研复试真题,华科计算机考研复试机试题(2000-2013)

    华科计算机考研复试机试题(2000-2013),c++实现,注本人参加过2014年华科上机考试,老师说机试时可以使用c语言,c++语言. 2000年 阶乘 #include #include #inc ...

  6. 大连理工大学 计算机复试分数线,2020大连理工大学考研复试分数线已公布

    2020大连理工大学考研复试分数线已公布!点击查看>>34所自划线院校2020考研复试分数线.2020考研国家线已公布,当前2020考研考生需全力准备考研复试/调剂工作>>备战 ...

  7. 复旦计算机考研复试要口试吗,2017复旦大学考研复试:英语口语面试常见问题汇总...

    2017复旦大学考研复试:英语口语面试常见问题汇总本站小编 辅仁网/2017-12-29 A magazine publisher is trying to decide how many magaz ...

  8. 山师计算机学硕分数线,2020山东师范大学考研复试分数线已公布

    2020考研已渐入尾声,但各研招院校考研复试分数线仍是考研人群关注重点.了解分数线是考研过程中的第一步,以便于给自己制定一个要求.2020山东师范大学考研复试分数线已公布!点击查看~ 2020年各招生 ...

  9. 复旦大学计算机应用复试线,2019年复旦大学考研复试分数线已出现

    考研复试备考除了复习,考研调剂也是需要重点关注的.下面由出国留学网小编为你精心准备了"2019年复旦大学考研复试分数线已出现",持续关注本站将可以持续获取更多的考试资讯! 2019 ...

最新文章

  1. 4- flutter - Widget
  2. 有人说:穷学IT富搞金融!程序员究竟是不是一帮苦孩子在做?
  3. 生物信息通识技术研讨会
  4. Redis 源码走读(二)对象系统
  5. InceptionNet V3整理总结
  6. [译]使用asp.net mvc 的工具提示
  7. 百度云2019落地第一枪打响:两款智能边缘硬件,让城市环卫、农药喷洒都AI起来...
  8. php几个问题的记录
  9. win10电脑黑屏只有鼠标箭头_电脑开机就黑屏,只显示鼠标怎么办?别急,简单几步,轻松解决!...
  10. 编译安装Nginx以及配置运行Drupal 8,实现上传进度功能
  11. [Unity3D]ml-agent入门案例
  12. 杭州电子科技大学计算机专业考研分数线,2021年杭州电子科技大学计算机考研分数线等数据分析...
  13. android 仿美团日历,仿小米日历 纵享丝滑切换的周月效果
  14. 汇编3-计算机程序是如何运行的
  15. php是什么电器元件,看完这个保证你认识“贴片电路板上”的每一个电子元件
  16. Linux Ubuntu下载
  17. 揭秘电信“龙计划”:合约手机将执行“四统一”
  18. 如何查看mysql的安装路径
  19. Anaconda虚拟环境中使用playsound测试报错 cannot import name ‘_gi‘ from ‘gi‘
  20. 全网独家解决方案: doccano报错 Your models in app(s): ‘api‘ have changes that are not yet reflected in a migrat

热门文章

  1. 转战物联网·基础篇01-物联网之我见
  2. 基于核函数加权直方图的Mean Shift目标跟踪 (二维颜色直方图)
  3. 圣思园——Java SE Lesson 2
  4. 打开viewer.jnlp文件
  5. Pytest注册使用自定义mark标签
  6. Python - 升级pip时提示拒绝访问
  7. AD21调整PCB大小操作步骤!
  8. 使用Python+selenium实现自动化测试脚本实例
  9. 2021常见user_agent大全 用户浏览器ua(互联网项目自己整理)
  10. android开发平台的框架原理,赶紧收藏起来