前言:由于时间问题,部分题解取自网友,但都是做过的好题。
对于有些用c++实现的题目,可以转化成c实现,cin看成c的读入,可以用scanf,输出cout看作printf,endl即换行符
开胃菜:
第一题:求简单交错序列前N项和
思路
要求和,我先定义一个sum来装每一项(注意有精度要求),然后每一项定义为item。然后观察可以知道,分母通项=4n-3,并且奇数项为正,偶数为负,所以等下来个if判断给他乘-1;
第二题:最小回文数:
分析:
核心的的思路就是要输出比n大的最小的回文数,我们可以这样,把n自增的数传入判断为回文数的函数里去,如果是就跳出循环记录此时的值,然后输出。
数组:
第一题:矩阵的对角线求和
分析:
先是主对角线,就是从左上到右下的那条线,我们可以直观的发现它的行列坐标是相等,所以在C语言中的表现形式就是i==j;
然后是副对角线,从右上到左下,通过观察我们可以发现在3*3矩阵中,副对角线上的元素行列坐标相加是等于4,但是这里要注意的是:在C语言中数组的下标是从0开始的。所以表现形式为:i+j==2。
#include<stdio.h>
int main()
{
int a[3][3];
int i,j,sum1 = 0,sum2 = 0;
for(i=0; i<3; i++){
for(j=0; j<3; j++){
scanf("%d",&a[i][j]);
}
}
for(i=0; i<3; i++){
for(j=0; j<3; j++){
if(i == j)
sum1 += a[i][j];
if(i + j == 2)
sum2 += a[i][j];
}
}
printf("%d %d\n",sum1,sum2);
return 0;
}
第二题:数组插入处理
分析:
首先是输入只含有9个元素的数组a[10],用for循环依次输入。接着输入插入的数字m,将m与数组元素比较。
1、当m<=a[0]时,记录t=0;
2、当m>=a[8]时,记录9;
3、当a[i]<=x<=a[i+1]时,记录x应该插入的位置t=i+1。
但是插入m之前要把元素往后移位,从后往前直到位置t,最后把m赋值给a[t],用for循环输出排好的a[10]。
注意事项:1、找插入位置时注意break退出遍历循环,不然就会出错误;
2、移位从后往前,不然从前往后会使数据丢失。
#include<stdio.h>
int main()
{
int a[10], i, m, t;
for (i = 0; i < 9; i++)
{
scanf("%d", &a[i]);
}
a[9] = 0;
scanf("%d", &m);
if (m <= a[0])
t = 0;
if (m >= a[8])
t = 9;
for (i = 0; i < 9; i++)
{
if (m >= a[i] && m <= a[i + 1])
{
t = i + 1;
break;
}
}
for (i = 9; i > t; i--)
{
a[i] = a[i - 1];
}
a[t] = m;
for (i = 0; i < 10; i++)
{
printf("%d", a[i]);
printf("\n");
}
return 0;
}
第三题:数字逆序输出
分析:
1.题目要求是输入十个整数。
2.所以我们定义数组长度为10就可以了。
3.利用for循环输入与输出。
#include<stdio.h>
int main()
{
int a[10],i,j;
for(i=0;i<10;i++) //注意这边是从i=0开始,到i<10
scanf("%d",&a[i]);
for(j=9;j>=0;j--) //数组逆序输出,我们可以从j=9开始,一直做到j<0,就结束循环
printf("%d ",a[j]); //注意这边输出要空格隔开
return 0;
}
第四题:数组替换
分析:
过于简单,看代码即可,适合小白中的小白
using namespace std;
#include<bits/stdc++.h>
int main()
{
int X[10];
for (int i = 0; i < 10; i++)
{
cin >> X[i];
if (X[i] <= 0)
X[i] = 1;
}
for (int i = 0; i < 10; i++)
{
printf("X[%d] = %d\n", i, X[i]);
}
}
第五题:最小数和它的位置
上码:
#include<bits/stdc++.h>
using namespace std;
int main()
{
int min = 1001, n, arr[1001], flag;
cin >> n;
for (int i = 0; i < n; i++)
{
cin >> arr[i];
if (arr[i] < min)
{
flag = i;
min = arr[i];
}
}
cout << "Minimum value: " << min << endl;
cout << "Position: " << flag;
return 0;
}
第六题:数组的右上半部分
思路:
首先 创建二维数组,然后观察规律,行数是从0-10,列数是1-11,所以我从第一行开始遍历,然后关键是列数的区间,列数第一行是11个,并且逐层减1,那么你可以在纸上模拟一下,当i=0,j=11,j是我要求的个数,然后i=1,j=10,得出规律,即可
第七题:数组的下方区域
思路:
寻找规律,遍历列数,i为行数,j为列数,行数和列数的和为11,得出规律即可实现
#include<bits/stdc++.h>
using namespace std;
int main()
{
char a;
cin >> a;
double M[12][12], sum = 0, cnt = 0;
for (int i = 0; i < 12; i++)
{
for (int j = 0; j < 12; j++)
{
cin >> M[i][j];
}
}
for (int i = 7; i <= 11; i++)
{
for (int j = 12 - i; j <= i - 1; j++)
{
sum += M[i][j];
cnt++;
}
}
if (a == 'S')
{
printf("%.1lf", sum);
}
else if (a == 'M')
{
printf("%.1lf", sum/cnt);
}
return 0;
}
第八题:有趣的跳跃
分析:
1.标记flag为1
2.输入数字 ,存放在一个数组中
3.进行相邻数相减,并取绝对值,存放在另一个数组中
4.对另一个数组进行从小到大排序
5.判断,如果出现了第i个差的值不等于i的情况,这flag标为0
6.判断,输出
#include<stdio.h>
#include<math.h>
int main()
{
long long int n,i,j,t;
int flag=1;//标记flag为1
scanf("%lld",&n);
int a[n],b[n-1];
for(i=0;i<n;i++)
scanf("%lld",&a[i]);//输入数字,存放在一个数组中
for(i=0;i<n-1;i++)
b[i]=abs(a[i+1]-a[i]);//进行相邻数相减,并取绝对值,存放在另一个数组中
for(i=0;i<n-1;i++)
{
for(j=i+1;j<n-1;j++)
{
if(b[j]<b[i])
{
t=b[i];
b[i]=b[j];
b[j]=t;//对另一个数组进行从小到大排序
}
}
}
for(i=0;i<n-1;i++)//判断
{
if(b[i]!=i+1)
{
flag=0;
break;//如果出现了第i个差的值不等于i的情况,这flag标为0
}
}
if(flag)//判断,输出
printf("Jolly");
else
printf("Not jolly");
return 0;
}
第九题:校门外的树
思路:
定义一个数组;数组下标代表数轴上的每个整数点即0,1,2,……,n(长度为500的公路有501颗树);
把这个数组初始化全为1(为1代表有树,0代表被移除);
输入移除区域(x,y),把这个区域上的树全置0;(有多个,用循环控制);
输出为1的树的数目;
//C++
#include <iostream>
using namespace std;
int main()
{
int L,M,x,y,a[10001];
cin>>L>>M;
for(int i=0;i<=L; i++) //先将数组全赋值为1
a[i]=1;
for(int i=0; i<M; i++)
{
cin>>x>>y; //[x,y]为区域区间
for(int j=x; j<=y; j++) //将区域区间内的值赋为0
a[j]=0;
}
int sum=0;
for(int i=0; i<=L; i++)
{
if(a[i]==1) //如果数组元素值是1 则计数加1
sum++;
}
cout<<sum;
return 0;
}
如果用c和c++其实是可以互换的,
//C
#include <stdio.h>
//初始化数组值为1
void InitArray(int *a,int num)
{
for(int i=0; i<=num; i++)
{
a[i]=1;
}
}
//将要移除的区域(x,y)置为0
void InitZero(int *a,int x,int y)
{
for(int i=x; i<=y; i++)
{
a[i]=0;
}
}
//输出值为1的即为结果
void Result(int *a,int L)
{
int sum=0;
for(int i=0; i<=L; i++)
{
if(a[i]==1)
sum++;
}
printf("%d",sum);
}
int main()
{
int a[10001]; //题意L<=10000
int L,M,x,y;
while(scanf("%d%d",&L,&M))
{
InitArray(a,L);
for(int i=0; i<M; i++)
{
scanf("%d%d",&x,&y);
InitZero(a,x,y);
}
Result(a,L);
}
return 0;
}
第十题:陶陶摘苹果
思路:
#include<iostream>
using namespace std;
int main()
{
int a[10],n,i,sum=0;
for(i=0;i<10;i++)
{
cin>>a[i];
}
cin>>n;
for(i=0;i<10;i++)
{
if(a[i]<=n+30)
sum++;
}
cout<<sum;
return 0;
}
函数
第一题:自定义函数求一元二次方程
分析:
先知道求解公式
如果无实数根
第二题:自定义函数之字符串反转
分析:
首先说一下会用到的标准库函数,gets(),puts(),strlen(),前两个是在头文件stdio.h中,后一个是在string.h里,用法如下:
1、gets():与scanf("%s",s)相似,但不完全相同,使用scanf("%s",s) 函数输入字符串时存在一个问题,就是如果输入了空格会认为字符串结束,空格后的字符将作为下一个输入项处理,但gets()函数将接收输入的整个字符串直到遇到换行为止。
2、puts(): puts 和 printf的用法一样,puts()函数的作用与语句“printf("%s\n",s);的作用相同。注意:puts在输出字 符串后会自动输出一个回车符。
3、strlen():使用格式strlen(s)。返回s的长度,不包括结束符NULL。
其次我们的思路是申明一个exchange()函数用来做逆序,方法是:
b数组的第一个元素存储a数组的最后一个元素。l是数组a的长度,具体看代码,一目了然。
注:在将数组a的值赋给b数组之后,需要加一个b[j] = '\0'语句,不然会很烫的!这是因为我在将a的值赋给b的过程中并非是所有元素都有赋值,并且末尾没有结束符,而puts()输出字符串时要遇到'\0’也就是字符结束符才停止,所以要加上一句b[j] = '\0';
#include<stdio.h>
#include<string.h>
int exchange(char a[],char b[])
{
int i,l,j = 0;
l = strlen(a);
for(i=l-1; i>=0; i--){
b[j] = a[i];
j++;
}
b[j] = '\0'; //给末尾加上结束符。
return 0;
}
int main()
{
char a[1000],b[1000];
gets(a);
exchange(a,b);
puts(b);
return 0;
}
第三题:自定义函数之字符串连接
分析:
此题可用指针来实现,即定义两个指针,用一个指针指向第二个字符的末尾\0,然后通过将
第用第一个指针指向第一个字符串的首元素,不断赋值到第二个字符串,直到第一个指针指向\0
然后记得添上\0。
//连接两个字符串,思路就是s接受的是str1的地址,t接受的是str2的地址,那么要把t赋值到s的末端,只需
//指向str1的指针s自增到/0的位置,然后把str2赋给str1,同时两种指针向后移动
//char* str_cat(char* s, char* t)
//{
// char* p = s;
// while (*s != '\0')
// {
// s++;
// }
// //出循环的时候s指向的是/0位置
// //开始把str2赋给str1;
// int i = 0;
// while (*(t+i) != '\0')
// {
// *(s+i) = *(t+i);
// i++;
// }
// *(s + i) = '\0';
// return p;
//}