某名校考研自命题C++程序设计——近10年真题汇总(下)

发布于:2024-12-18 ⋅ 阅读:(12) ⋅ 点赞:(0)

第二期,相比上一贴本帖的题目难度更高一些,我当然不会告诉你我先挑简单的写~


某名校考研自命题C++程序设计——近10年真题汇总(上)-CSDN博客文章浏览阅读651次,点赞9次,收藏13次。本帖更新一些某校的编程真题,总体来说不难,考察的都是基本功,92高校大一期末的难度,不过有些细节颇为繁琐,各位还是需要一定程度上注意的~https://blog.csdn.net/jsl123x/article/details/144354818?spm=1001.2014.3001.5501

一.原地排序两个混乱数组

不算太难,无非就是把第二个数组中较小的元素插到第一个数组里面,然后一号里面大的放到二号里面,虽然说不允许降序处理,不过由于两个数组本身均为非降序,所以其实处理其来也很容易,遍历一遍即可~ 

因为这里的数组并非等长且未事先规定,这里我们要用到自动结束输入的操作,具体看这一片博客:

C++通过回车结束循环输入_c++输入回车结束输入-CSDN博客文章浏览阅读4.6k次,点赞2次,收藏7次。文章介绍了如何使用C++编程处理不确定数量的数字输入。通过定义一个包含行数和数值的结构体,利用vector存储数据,读取每一行的字符直到遇到换行符,然后将数据添加到结构体实例中。最后,通过迭代器输出所有存储的数值及其对应的行号。https://jslhyh32.blog.csdn.net/article/details/131623031

不过为了方便描述思想,博主这里就采用规定好的长度了,大家自行完成不定长模式:

#include <iostream>
#include <vector>
using namespace std;
 
void Swap(int &x,int &y){
	int t=x;
	x=y;
	y=t;
} 
 
void fun(vector<int> &a,vector<int> &b,int lena,int lenb)
{
	int Min_loca=0;//在b数组中找到最小的数! 
	for(int i=0;i<lena;i++)
	{
		for(int j=0;j<lenb;j++)
		{
			if(b[j]<b[Min_loca])
				Min_loca=j;
		}
		if(b[Min_loca]<a[i]) //如果b中最小的数比当前a中的小,就对换~ 
			Swap(a[i],b[Min_loca]);
	}
	//对b重新排序 
	for(int i=0;i<lenb;i++)
	{
		Min_loca=i;
		for(int j=i;j<lenb;j++)
			if(b[j]<b[Min_loca])
				Min_loca=j;	
		Swap(b[i],b[Min_loca]);
	}
} 
 
 
int main(int argc, char** argv) {
	int n1=0,n2=0;
	cin>>n1>>n2;
	vector<int> V1,V2;
	int temp=0;
	for(int i=1;i<=n1;i++)
	{
		cin>>temp;
		V1.push_back(temp);
	}
	for(int i=1;i<=n2;i++)
	{
		cin>>temp;
		V2.push_back(temp);
	}
	fun(V1,V2,n1,n2);
	for(int i=0;i<=V1.size()-1;i++)
		cout<<V1[i]<<" ";
	cout<<endl;
	for(int i=0;i<=V2.size()-1;i++)
		cout<<V2[i]<<" ";

	return 0;
}

二.人造词汇表

这题很简单的操作,先掌握一个小技巧,如下的getline函数可以接受空格字符串:(这是getline头文件里面的~)

#include <iostream>
#include <vector>
#include <string>
using namespace std;
int main(int argc, char** argv) {
	string s;
	getline(cin, s);
	cout<<s;
}

 

其实大家会了这个就很简单了,没什么好说的。至于他说的不能重复且要排序,博主这里直接用的STL里面的set容器——其实有点耍赖了,不过该校考纲里面明确可以使用C++,感觉也不算犯规嘻嘻。另外要注意set不能随机访问,必须用迭代器来完成遍历了~ 

题目里面还说了不能存在大写字母,上一篇已经讲过例题,大家可以自己完成,博主就不再赘述了~ 

三.向量的最小内积

点乘就是内积,考研选手应该很熟悉~ 对于输入的两组向量进行排序,一组从大到小、另一组从小到大。接着,这两组向量计算所得的内积即为最小内积。

#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

int main(int argc, char** argv) {
	
	int n=0;
	vector<int> V1,V2;
	cin>>n;
	int temp=0;
	for(int i=1;i<=n;i++)
	{
		cin>>temp;
		V1.push_back(temp);
	}
	for(int i=1;i<=n;i++)
	{
		cin>>temp;
		V2.push_back(temp);
	}
	sort(V1.begin(),V1.end());
	sort(V2.begin(),V2.end());
	reverse(V2.begin(),V2.end());
	int count=0;
	for(int i=0;i<=n-1;i++)
		count+=V1[i]*V2[i];
	cout<<count; 
	 
	return 0;
}

没什么bug。

四.元音和辅音字母

又是那种多种if条件判断的题目——没错和黑色星期五一样恶心,截图给大家看一下答案就好,这题现在肯定不会再考了~

 

 

五.就地循环左移

具体题目找不到了,不过很简单,对元素循环左移N位,只要能理清楚下标就很容易~

#include <iostream>
#include <vector>
using namespace std;
 
void ShiftLeft(vector<int> &V,int x)
{
	vector<int> temp;
	for(int i=1;i<=x;i++)
		temp.push_back(V[i-1]);//将前x位拷贝进临时数组~ 
	for(int i=x;i<=V.size()-1;i++)
		V[i-x]=V[i];
		//1 2 3 4 5 6 (2)  3 4 5 6 1 2
	for(int i=V.size()-x,j=0;i<=V.size()-1;i++,j++)
		V[i]=temp[j];
} 
 
int main(int argc, char** argv) {
	int n=0;
	cin>>n;
	vector<int> V;
	for(int i=1;i<=n;i++)
		V.push_back(i);
	for(int i=0;i<=V.size()-1;i++)
		cout<<V[i]<<" ";	
	ShiftLeft(V,3);
	cout<<endl;
	for(int i=0;i<=V.size()-1;i++)
		cout<<V[i]<<" ";
	return 0;
}

这里测试左移3位,没什么问题:

六.奇数偶数对调

依旧是老毛病,很有歧义,我们姑且认为:奇数和偶数内部之间是没有顺序要求的。可以直接用双指针,一个从头找奇数,另一个从尾找偶数,两者都找见以后再进行对调~

#include <iostream>
#include <vector>
using namespace std;
 
void Swap(int &x,int &y){
	int t=x;
	x=y;
	y=t;
} 
 
void change(vector<int> &V)
{
	int i=0,j=V.size()-1;
	while(i<j){
		while(i<j&&V[i]%2==1)//只要是奇数就一直往后找 
			i++;
		while(i<j&&V[j]%2==0)//只要是偶数就一直往前找 
			j--;
		if(i<j)
			Swap(V[i],V[j]);
	}
} 
 
 
int main(int argc, char** argv) {
	int n=0;
	cin>>n;
	vector<int> V;
	for(int i=1;i<=n;i++)
		V.push_back(i);	
	change(V);
	for(int i=0;i<=V.size()-1;i++)
		cout<<V[i]<<" ";
	return 0;
}

没什么问题~

 

七.统计【1】的个数

直接把每个整数的每一位都分离开来,然后对比是否为【1】即可。

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

int main() {
	vector<int> V;
	int n=0,temp=0;
	cin>>n;
	temp=n;
	for(int i=1;i<=n;i++)
		V.push_back(i);
	for(int i=0;i<=n-1;i++)
		cout<<V[i]<<" "; 
	cout<<endl;
	int length=0; 
	while(temp!=0)
	{
		temp/=10;
		length++;
	}
	
	int count=0;
	for(int i=0;i<=n-1;i++)
	{
		int j=1;
		while(j<=length)
		{
			if(V[i]%10==1)
				count++;
			V[i]/=10;
			j++;
		}
	}
	cout<<"1的个数为:"<<count<<endl;
	return 0; 
}

非常简单,没什么bug~ 

八.非递归的归并排序

没什么难度,各位一定要想清楚所谓的自顶向下自底向上:递归的归并排序是将数列不断划分为有序序列——也即只有一个元素的时候,再不断归并;而非递归则一开始就把每一个元素看做一个单独的有序序列,再不断合并。这里给出伪码,主要是看思想:

void MergeSortNonR(int* a, int n)
{
	int* tmp = (int*)malloc(sizeof(int) * n);
	assert(tmp);
	int gap = 1;
	//外层循环,控制gap的值,gap每次增加二倍
	while (gap < n)
	{
		//n是数组元素个数
		for (int i = 0; i < n; i += 2 * gap)
		{
			//归并 [i,i+gap-1] [i+gab,i+2*gap-1]
			int begin1 = i, end1 = i + gap - 1;
			int begin2 = i + gap, end2 = i + 2 * gap - 1;
 
			//处理边界值
 
			//如果是 end1 越界或者 begin2 越界,直接退出即可,不需要归并
			if (end1 >= n || begin2 >= n)
			{
				break;
			}
			//如果是 end2 越界。需要归并
			if (end2 >= n)
			{
				end2 = n - 1;
			}
			int index = i;
			while (begin1 <= end1 && begin2 <= end2)
			{
				if (a[begin1] < a[begin2])
				{
					tmp[index++] = a[begin1++];
				}
				else
				{
					tmp[index++] = a[begin2++];
				}
			}
			while (begin1 <= end1)
			{
				tmp[index++] = a[begin1++];
			}
			while (begin2 <= end2)
			{
				tmp[index++] = a[begin2++];
			}
 
			//小区间优化拷贝回数组a
			for (int j = i; j <= end2; j++)
			{
				a[j] = tmp[j];
			}
		}
		gap *= 2;
	}
	//释放
	free(tmp);
	tmp = NULL;
}

九.统计整数个数

由于是回忆版,肯定不太严谨——实际上只有0-9这10种整数。这题也非常简单,直接用散列表秒杀~

#include <iostream>
using namespace std;

 
int main() {
	int hash[10]={0};
	int n=0,temp=0;
	cin>>n;
	for(int i=1;i<=n;i++)
	{
		cin>>temp;
		hash[temp]++;
	} 
	for(int i=0;i<=9;i++)
		cout<<i<<"出现了:"<<hash[i]<<"次~"<<endl;
	return 0; 
}

非常简单~ 

 

十.移动学生

无算法的基础题,感觉大一的oj平台特别喜欢出这种题目。。。

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

struct target{
	int num;//学生序号 
	int time;//移动次数 
};

int main(int argc, char** argv) {
	int student[10]={1,2,3,4,5,6,7,8,9,10};//题目没要求,我们这里用10模拟
	int m=0;
	cin>>m;
	int q=0,p=0;
	vector<target> V;
	target temp;
	for(int i=1;i<=m;i++)
	{
		cin>>q>>p;
		temp.num=q;
		temp.time=p;
		V.push_back(temp);
	}
	for(int i=0;i<=V.size()-1;i++)
		cout<<V[i].num<<" "<<V[i].time<<endl; 
	for(int i=0;i<=V.size()-1;i++){
		int q=V[i].num-1;//定位目标学生
		int p=q+V[i].time;//定位另一个参与交换的学生
		int s=0;
		s=student[q];
		student[q]=student[p];
		student[p]=s; 
	}	 
	for(int i=0;i<=9;i++)
		cout<<student[i]<<" ";
}

其实这题出的不好——没有明确说明是按照原来的序号执行移位还是现有的序号执行移位,也没说明越界能不能循环移动。这里我们默认是按现有的排序,且不能循环移动,测试一下:

如上,一共移位3次:

  • 2号前移一位
  • 3号后移一位
  • 9号后移一位

没什么bug~ 


统计结束,仅供大家参考~


网站公告

今日签到

点亮在社区的每一天
去签到