本帖更新一些某校的编程真题,总体来说不难,考察的都是基本功,92高校大一期末的难度,不过有些细节颇为繁琐,各位还是需要一定程度上注意的~
目录
一.分数求和
cpp
#include <iostream>
using namespace std;
int main(int argc, char** argv) {
int n=0;
cin>>n;
double answer=0.000;
for(int i=1;i<=n;i++)
{
if(i%2!=0)
answer+=(1.0/i);
else
answer-=(1.0/i);
}
cout<<answer<<endl;
return 0;
}
过于简单,唯一需要注意的地方是需要用1.0除以第n项的值,如果用1除永远是1,因为整数除不尽!
二.大小写字母转换
复习两个知识点:
1.ASCII码你好意思还没背会?小写字母反而大,大小相差32,大写A为65,小写a为97------一定要记清楚!
2.在初试考文件已经过时了,要是觉得不保险把这篇帖子的内容掌握即可:一篇入门C语言【文件】-CSDN博客文章浏览阅读609次,点赞3次,收藏6次。本科期间C语言的课本无论哪个版本都会有【文件】这一章节,不过好多学校基本上不讲或者就出一道选择题,讲得很浅,今天这篇详细总结一下这部分的知识~https://blog.csdn.net/jsl123x/article/details/141827614?spm=1001.2014.3001.5501
cpp
#include <iostream>
#include <string>
using namespace std;
int main(int argc, char** argv) {
string s;
cin>>s;
for(int i=0;i<=s.size()-1;i++)
if(s[i]>=97&&s[i]<=122)
s[i]-=32;
cout<<"大写形态为:"<<s<<endl;
FILE* p;
p=fopen("./text.txt","r+");
for(int i=0;i<=s.size()-1;i++)
fputc(s[i],p);
fclose(p);
}
结果没什么问题:
这里博主用的是r+,也即十进制的读写,实际上也可以用a+也即二进制的读写,大家看题目要求~
三.判断当年天序
输入格式为2024 12 09,然后判断这是今年的第几天,很简单,只需要用一个类似哈希表的数组存储每个月的天数即可,如果是闰年可能会要多一天。
cpp
#include <iostream>
#include <string>
using namespace std;
struct Date{
int year;
int month;
int day;
};
int main(int argc, char** argv) {
int days[12]={31,28,31,30,31,30,31,31,30,31,30,31};
int answer=0;
Date date;
cin>>date.year>>date.month>>date.day;
if((date.year%400==0)||(date.year%100!=0&&date.year%4==0)) //闰年!
days[1]++;//二月要多一天,别搞混数组下标
for(int i=0;i<=date.month-2;i++)
answer+=days[i];
answer+=date.day;
cout<<"这是"<<date.year<<"的第"<<answer<<"天~"<<endl;
}
几点说明:
- 博主用的结构体,其实写完以后觉得有点多余。。。直接定义变量就行了,大家没必要学我
- days存放每个月不是闰年的天数
- 然后单独判断是否为闰年------可以整除400亦或整除4的同时不能整除100------如果是闰年2月要加一天
- 注意数组的下表,你要是晕,就直接把0位空出来从一开始赋值
- 最后加上当月天数即可~
测试后没什么问题~
四.交替合并字符串
唉,写得我都觉得乏味,但是做事一定要有头有尾哈哈~
cpp
#include <iostream>
#include <string>
using namespace std;
int main(int argc, char** argv) {
string A,B;
cin>>A;
cin>>B;
int i=0,j=0;
string target;
while(i<=A.size()-1&&j<=B.size()-1)
{
target+=A[i++];
target+=B[j++];
}
while(i<=A.size()) target+=A[i++];
while(j<=B.size()) target+=B[j++];
cout<<target<<endl;
FILE* p;
p=fopen("./text.txt","r+");
for(int i=0;i<=target.size()-1;i++)
fputc(target[i],p);
fclose(p);
}
- 本质上就是用两个指针分别扫描两个字符串------各位一定要注意这种操作:在双指针类的题目,亦或什么n复杂度内实现字符串的逆转,经常会这么写。
- 此外就是扫描长度------这里是直到扫描完一个才单独扫描另一个,其实就是归并排序经典的写法。里面的【i++】各位一定要理清楚,这是先操作,再自增~
测试一下也没什么问题~
五.指针形态的冒泡排序
该说不说,有点"装神弄鬼",姑且理解为他想考察指针数组吧。。。代码如下:
cpp
#include <iostream>
#include <string>
using namespace std;
void BubbleSort(char* arr[],int length)
{
for(int i=0;i<=length-1;i++)//忽略最后一位
for(int j=i+1;j<=length;j++)
if((*arr[i])>(*arr[j]))
{
char* temp=arr[i];
arr[i]=arr[j];
arr[j]=temp;
}
}
注意,上面传进来的是一个存储了元素地址的指针数组,而并非元素的值,因此:
- 我们在比较大小时,应该对指针进行解引用,不然比较的是地址的大小
- 但在交换的时候,只需要交换元素的地址即可~
- 此外,最外层循环可以少对比一位,这时冒泡的基本功了,别糊涂
cpp
int main(int argc, char** argv) {
string target;
cin>>target;
char* arr[target.size()-1];
for(int i=0;i<=target.size()-1;i++)
arr[i]=&target[i];
cout<<"排序前:";
for(int i=0;i<=target.size()-1;i++)
cout<<(*arr[i])<<" ";
cout<<endl;
BubbleSort(arr,target.size()-1);
cout<<"排序后:";
for(int i=0;i<=target.size()-1;i++)
cout<<(*arr[i])<<" ";
return 0;
}
主函数测试一下。
没什么毛病~
六.递归方式的倒序输出
虽然递归的时间复杂度很高,实践中肯定不这样写,但是作为思维的练习值得关注~
cpp
#include<iostream>
using namespace std;
void MyReverse(char* string)
{
if (*string != '\0')
MyReverse(string + 1);
printf("%c", *string);
}
int main()
{
char arr[1000];
cin>>arr;
MyReverse(arr);
return 0;
}
如果当前不为【\0】,就一直向后递归,直到为\0后再递归输出前面的字母,以此实现逆序~
这里就不输出到文件中了,和前面同理~
七.黑色星期五
没什么技术含量,就是编起来细节比较多,这种题只要能读懂题干,考出来不怕他~~
cpp
#include <iostream>
using namespace std;
int main(){
int n=0,num=1; //1900.1.1是星期一因此,这个一般在题干会给出~
cin>>n;
int year=1900,month,day=0;//从1900年开始向后遍历
int count[7]={0};
int mon[13]={0,31,28,31,30,31,30,31,31,30,31,30,31};
for(int i=0;i<n;i++,year++){
if((year%4==0&&year%100!=0)||year%400==0)
mon[2]=29;
for(month=1;month<13;month++)
for(day=1;day<=mon[month];day++){
if(day==13)
count[num]+=1;
num=(num+1)%7;
}
mon[2]=28;
}
cout<<count[6]<<endl;
for(int i=0;i<5;i++)
cout<<count[i]<<" ";
cout<<count[5]<<endl;
return 0;
}
八.卡布列克运算
还是和黑色星期五一样,没有任何思维上的难度,只是操作的技巧问题:
cpp
#include <iostream>
#include <vector>
#include <cmath>
#include <algorithm>
using namespace std;
int main(){
int n=0;
cin>>n;
vector<int>V;
int max=0,min=0;
int temp=0;
while(n)
{
temp=n%10;
n/=10;
V.push_back(temp);
}
sort(V.begin(),V.end()); //排序后为从小到大
for(int i=3;i>=0;i--){
min+=V[3-i]*pow(10,i);
max+=V[i]*pow(10,i);
}
cout<<max-min<<endl;
}
博主还是用了大量的STL标准库,各位想自己写一些底层操作也可以,博主就浅浅偷懒一下了~
测试如下,没问题:
九.只出现一次的字符
简单,博主的思维是可以使用结构体类型的哈希表,这样只需要遍历一次即可出结果------因为这里限制为英文字母,哈希表长度为26,遍历哈希表在N很大的情况下可以看为常数级别。还有一点要复习,字符串的0和大小字母A的差值为65,大家一定要记清楚,这一点可以有效帮助我们构造散列函数,也即如下这一段:
cpp
for(int i=0;i<=target.size()-1;i++)
{
int temp=0;
temp=target[i]-65;
hash[temp].count++;
if(hash[temp].first==-2)
hash[temp].first=i;
}
不过非常遗憾,可能是电脑的问题,博主写的代码出现了找不到的bug------即遍历哈希表会出现意想不到的情况,只能把哈希表冒泡排序了一遍。。。其实大家可以试试找出哈希表中first最小的值即可,复杂度为n。这段加了冒泡的是n方,也还行吧。。。
cpp
#include <iostream>
#include <string>
using namespace std;
struct Hash{
int count;
int first;
char tag;
};
int main(){
string target;
cin>>target;
Hash hash[26];
for(int i=0;i<=25;i++)
{
hash[i].count=0;
hash[i].first=-2;
hash[i].tag='A'+i;
}
for(int i=0;i<=target.size()-1;i++)
{
int temp=0;
temp=target[i]-65;
hash[temp].count++;
if(hash[temp].first==-2)
hash[temp].first=i;
}
for(int i=0;i<=24;i++)
for(int j=i+1;j<=25;j++)
if(hash[i].first>=hash[j].first)
{
Hash temp;
temp=hash[i];
hash[i]=hash[j];
hash[j]=temp;
}
for(int i=0;i<=25;i++)
if(hash[i].count==1)
{
cout<<"第一个只出现一次的字母是:"<<hash[i].tag<<endl;
break;
}
return 0;
}
测试一下,没什么bug:
十.产生0-1的随机数
非常冷门,了解一下即可:
cpp
#include <iostream>
#include <cstdlib>
using namespace std;
int main(int argc, char** argv) {
for(int i=1;i<=10;i++)
{
double num=0;
num=(double)rand()/100000;
cout<<num<<endl;
}
return 0;
}