PS:我也不懂为什么文章突然就变成VIP文章了,导致后面的内容看不了,需要完整版本的话,可以关注我的公众号
发送信息在后台,我看到就会回复~
写在前面的话:
2019年华中科技大学软件学院的复试已经尘埃落定,为了机试也刷了一下历年的软院上机题,虽然并没有用到(2019年软院专硕没有上机),为了造福学弟学妹们,把自己写的代码放出来,仅供参考。
注:使用的c/c++编写的,由于篇幅较长,分为上篇和下篇,上篇为2017年——2013年真题,下篇为2012年——2007年真题加我自己拓展的一些跟历年真题类似的题目,代码中都含题目描述,其中2018年跟2019年软院没有机试,文末也放了pdf的链接供下载
祝都能考上自己心仪的学校!
2012-1-平方回文数(与2013-1相同)
2012-2-约瑟夫环
#include <iostream>
#include <string>
using namespace std;
/*========================================
约瑟夫环
一群人(排列的编号从 1 到 N,N 可以设定)围成一圈,按一定规则出列。剩余的人仍
然围成一圈,出列规则是顺着 1 到 N 的方向对圈内的人从 1 到 C 记数(C 可以设定)。圈内
记数为 C 的人出列。剩余的人重新计数。按上述规则,让圈内所有的人出列。请编程输出
出列编号的序列。
例:
若 N=3,C=1,则出列编号的序列为 1,2,3
若 N=3,C=2,则出列编号的序列为 2,1,3
分析:
方法一:链表,麻烦,省略
方法二:循环数组,
循环条件为:index = (index + 1) % count
初始alive = count,每出圈一个,alive --,
循环结束条件为:alive > 0
每一次循环,就是过一个人,该人在圈内还是圈外,圈内number++,圈外number不变,
故定义一数组circle[count],记录该编号是已出圈还是未出圈,圈内为0,圈外为1
number = number + 1 - circle[index]
malloc()只分配内存,calloc()除了分配内存外,还将分配的内存清空为0。
这两段代码等价
int* buffer = (int*)malloc(512 * sizeof(int));
memset(buffer, 0, 512 * sizeof(int));
int* buffer = (int*)calloc(512, sizeof(int));
by shinerise 2019/2/27
=============================================*/
void sequence(int count, int boom){
int number = 0;//number为计数
int alive = count;//alive表示是否全出圈
int index = 0;//index为下标
int *circle = (int*)calloc(count, sizeof(int));//创建数组,用于表示该元素是在圈内还是圈外,初始为0
while(alive > 0){
number = number + 1 - circle[index];
if(number == boom){
//出圈的操作
cout<<index + 1<<" ";
circle[index] = 1;//circle置为1表示在圈外
number = 0;//重新计数
alive --;
}
index = (index + 1)%count;
}
free(circle);
}
int main(){
int n, c;//n为总人数,第c个出圈
//cin空字符(包括回车,TAB,空格)都会当成一个输入的结束
cin>>n>>c;
sequence(n, c);
return 0;
}
2011-1-已知二叉树前序中序序列,输出后序序列
/*==================================
已知一颗二叉树 S 的前序遍历和中序遍历序列,请编程输出二叉树 S 的后续遍历序
列。
例:
输入:
pred[]/先序:A、B、D、E、C、F、G
inod[]/中序:D、B、E、A、C、G、F
输出:
后序遍历序列是:D、E、B、G、F、C、A
by shinerise 2019/2/27
=======================================*/
#include <iostream>
#include <string>
using namespace std;
const int N = 50;
typedef char ElemType;
typedef struct BiTree{
ElemType data;
struct BiTree *lchild;
struct BiTree *rchild;
}BiTree;
//获取元素ch在数组array中的下标,数组array长度为len
int getIndex(ElemType ch, ElemType *array, int len){
for(int i=0;i<len;i++){
if(array[i] == ch){
return i;
}
}
}
//构造二叉树根节点,pre为先序数组,in为中序数组,len为数组长度
BiTree *createBiTree(ElemType *pre, ElemType *in, int len){
if(len <= 0){
return NULL;
}
BiTree *root = new BiTree;
root->data = *pre;
int index = getIndex(*pre, in, len);
root->lchild = createBiTree(pre+1, in, index);
root->rchild = createBiTree(pre+1+index, in+1+index, len-index-1);
return root;
}
//后序遍历序列
void postOrder(BiTree *root){
if(root != NULL){
postOrder(root->lchild);
postOrder(root->rchild);
cout<<root->data;
}
}
int main(){
ElemType *pre = new ElemType[N];
ElemType *in = new ElemType[N];
cin>>pre;
cin>>in;
//strlen为数组长度
BiTree *root = createBiTree(pre, in, strlen(in));
postOrder(root);
cout<<endl;
return 0;
}
2011-2-循环数组输出下一个比这个元素更大的值
//循环数组输出下一个元素比这个元素更大的值
#include <iostream>
using namespace std;
int main(){
int n;
cin>>n;
int *str = new int[n];
for(int i=0;i<n;i++){
cin>>str[i];
}
for(int i=0;i<n;i++){
int j;
for(j=(i+1)%n;str[j]<=str[i]&&j!=i;j=(j+1)%n);
if(str[j]>str[i]){
cout<<str[j]<<" ";
}else{
cout<<-1<<" ";
}
}
return 0;
}
2010-1-下标为奇数的小写字母转化为大写字母(与2014-2相同)
2010-2-中国象棋马走日,只能向右
/*=========================================
在半个中国象棋棋盘(5*5)上,马在左上角(1,1)处,马走日字。
只能往右走,不能向左,可上可下。求从起点到(m, n)处有几种不同的走法
by shinerise 2019/2/28
==========================================*/
#include <iostream>
#include <string>
using namespace std;
const int ROW = 5;
const int COLUMN = 5;
int sum = 0;
int chess[ROW][COLUMN] = {0};
int xdir[4] = {-2, -1, 1, 2};
int ydir[4] = {1, 2, 2, 1};
//访问函数,x,y为此时坐标,m,n为要到达的位置
void visit(int x, int y, int m, int n){
if(x>=0&&x<COLUMN&&y>=0&&y<ROW&&chess[x][y]==0){
if(x==m&&y==n){
sum++;
return;
}
chess[x][y] = 1;
for(int i=0;i<4;i++)
visit(x+xdir[i], y+ydir[i], m, n);
chess[x][y] = 0;
}
}
int main(){
int m, n;
cin>>m>>n;
//为方便,从下标为0开始
visit(0, 0, m-1, n-1);
cout<<"有"<<sum<<"种走法"<<endl;
return 0;
}
2009-1-最长公共子串(与2017-1相同)
2009-2-已知二叉树前序中序遍历求后序遍历(与2011-1相同)
2008-1-斐波那契数列
#include <iostream>
#include <string>
using namespace std;
/*========================================
求数列 s(n)=s(n-1)+s(n-2)的第 n 项的值。其中 s(1)=s(2)=1。
输入:n,
输出:s(n)
by shinerise 2019/2/27
=======================================*/
int getNum(int n){
if( n==1 || n==2 ){
return 1;
}else{
return getNum(n-1)+getNum(n-2);
}
}
int main(){
int n;
cin>>n;
cout<<getNum(n);
return 0;
}
2008-2-水仙花数
/*=====================================
打印出所有的“水仙花数”,所谓“水仙花数”是指一个 3 位数,其各位数字立方和等于
该数本身。
例:153=1*1*1+3*3*3+5*5*5
by shinerise 2019/2/27
======================================*/
#include <iostream>
#include <string>
using namespace std;
int main(){
for(int i=100;i<1000;i++){
int a, b, c;//a,b,c分别为i的个位,十位,百位
a = i % 10;
b = i / 10 % 10;
c = i / 100;
if(i==(a*a*a+b*b*b+c*c*c)){
cout<<i<<endl;
}
}
return 0;
}
拓展1-已知中序后序求前序遍历序列
/*==================================
已知一颗二叉树 S 的后序遍历和中序遍历序列,请编程输出二叉树 S 的先序遍历序列。
by shinerise 2019/2/27
=======================================*/
#include <iostream>
#include <string>
using namespace std;
typedef struct BiTree{
char data;
struct BiTree *lchild;
struct BiTree *rchild;
}BiTree;
const int N = 50;
//获取元素在中序数组中的下标,ch为元素,array为数组,len为数组长度
int getIndex(char ch, char *array, int len){
for(int i=0;i<len;i++){
if(array[i] == ch){
return i;
}
}
}
//构造二叉树,post为后序数组,in为中序数组,len为数组长度
BiTree *createBiTree(char *in, char *post, int len){
if(len <= 0){
return NULL;
}
BiTree *root = new BiTree;
char ch = post[len-1];
root->data = ch;
int index = getIndex(ch, in, len);
root->lchild = createBiTree(in, post, index);
root->rchild = createBiTree(in+index+1, post+index, len-index-1);
return root;
}
//输出先序遍历序列
void preOrder(BiTree *root){
if(root != NULL){
cout<<root->data;
preOrder(root->lchild);
preOrder(root->rchild);
}
}
int main(){
char *in = new char[N];
char *post = new char[N];
cin>>in;
cin>>post;
BiTree *root = createBiTree(in, post, strlen(in));
preOrder(root);
cout<<endl;
return 0;
}
拓展2-子串在主串中匹配出现次数
//子串在主串中匹配,求子串出现的次数,不重复
#include <iostream>
using namespace std;
const int N = 255;
int main(){
char *str = new char[N];
char *substr = new char[N];
cin>>str;
cin>>substr;
int a = 0, b = 0;
int num = 0;//num记录次数
while(a<strlen(str)&&b<strlen(substr)){
if(str[a] == substr[b]){
if(b == strlen(substr) - 1){
num++;
a++;
b = 0;
}else{
a++;
b++;
}
}else{
a++;
b = 0;
}
}
cout<<num<<endl;
return 0;
}
拓展3-数字串中奇数移到偶数的前面
//将数组中奇数移到偶数前面
#include <iostream>
#include <string>
using namespace std;
int main(){
int n;
cin>>n;
int *str = new int[255];
for(int i=0;i<n;i++){
cin>>str[i];
}
int left = 0;
int right = n - 1;
int i = 0;
int count = 0;
while(count < n){
if(str[i]%2==1){
left++;
count++;
i++;
}else{
int temp = str[i];
str[i] = str[right];
str[right] = temp;
count++;
right--;
}
}
for(int i=0;i<n;i++){
cout<<str[i]<<" ";
}
cout<<endl;
return 0;
}
拓展4-已知满二叉树前序序列,求后序序列
//已知满二叉树先序遍历序列,求后序遍历序列
#include <iostream>
using namespace std;
void search(char *str, int len){
if(len<=0){
return;
}else{
int sublen = (len - 1)/2;
search(str+1, sublen);
search(str+1+sublen, sublen);
cout<<*str;
}
}
int main(){
char *str = new char[50];
cin>>str;
search(str, strlen(str));
return 0;
}
拓展5-比较两个字符串返回其字典序的大小
/*======================================
给定两个字符串,长度不超过100,字符串匹配,若相等,返回0,若不相等,返回ascii的差值
若str1>str2,差值为正,若str1<ste2,差值为负
by shine_rise 2019/3/9
====================================*/
#include <iostream>
#include <string>
using namespace std;
int main(){
string str1, str2;
cin>>str1>>str2;
int len1 = str1.length();
int len2 = str2.length();
int len = (len1<len2)?len1:len2;
int i = 0;
int index;
while(i<len){
if(str1[i]==str2[i]){
i++;
}else{
index = str1[i] - str2[i];
break;
}
}
if(i==len){
if(len1==len2){
index = 0;
}else if(len1>len2){
index = str1[i];
}else{
index = -str2[i];
}
}
cout<<"比较两个字符串的差值为"<<index<<endl;
system("pause");
return 0;
}
拓展6-大写字母转化为小写字母
/*=====================================
将全部字符串转换为小写字母,并将其中所有的连续子串转换为对应的缩写形式输出,
比如abcD 转换为a-d,其次,-至少代表1个字母,既如果是ab,则不需要转换为缩写形式。
by shinerise 2019/3/9
========================================*/
#include <iostream>
#include <string>
using namespace std;
int main(){
string str;
cin>>str;
int len = str.length();
for(int i=0;i<len;i++){
if(str[i]>='A'&&str[i]<='Z'){
str[i] = str[i] + 'a' - 'A';
}
cout<<str[i];
}
cout<<endl;
if(len==1||len==2){
cout<<"缩写形式为"<<str<<endl;
}else{
cout<<"缩写形式为"<<str[0]<<"-"<<str[len-1]<<endl;
}
system("pause");
return 0;
}
拓展7-字符串匹配
/*===============================
输入格式:匹配单词时,不区分大小写,但要求完全匹配,即给定单词必须与文章
中的某一独立单词在不区分大小写的情况下完全相同,
如果给定单词仅是文章中某一单词的一部分则不算匹配
共2行。
第1行为一个字符串,其中只含字母,表示给定单词,不区分大小写;
第2行为一个字符串,其中只可能包含字母和空格,表示给定的文章。
输出格式:
一行,如果在文章中找到给定单词则输出两个整数,两个整数之间用一个空格隔开,
分别是单词在文章中出现的次数和第一次出现的位置
(即在文章中第一次出现时,单词首字母在文章中的位置,位置从0开始);
如果单词在文章中没有出现,则直接输出一个整数-1
输入:
To
to be or not to be is a question
输出2 0
输入:
to
Did the Ottoman Empire lose its power at that time
输出:-1
by shinerise 2019/3/1
==============================*/
#include <iostream>
#include <string>
using namespace std;
int main(){
string str1, str2;
getline(cin, str1);
getline(cin, str2);
for(int i=0;i<str1.length();i++){
str1[i] = tolower(str1[i]);
}
for(int j=0;j<str2.length();j++){
str2[j] = tolower(str2[j]);
}
str1 = ' ' + str1 + ' ';
str2 = ' ' + str2 + ' ';
if(str2.find(str1)==string::npos){
cout<<-1<<endl;
}else{
int firstIndex = str2.find(str1);
int index = str2.find(str1);
int count = 0;
while(index != string::npos){
count++;
index = str2.find(str1, index+1);
}
cout<<count<<" "<<firstIndex<<endl;
}
system("pause");
return 0;
}
链接
华科软院复试2007-2017年上机题C++版本(上篇)
华科软院复试2007-2017年上机题C++版本pdf
https://pan.baidu.com/s/1xUc9702MNEwta1ga2zG80A
提取码:js8m