第二期,相比上一贴本帖的题目难度更高一些,我当然不会告诉你我先挑简单的写~
某名校考研自命题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 2for(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++];}//小区间优化拷贝回数组afor (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~
统计结束,仅供大家参考~