目录
1.数组插入元素并排序
【问题描述】
有一个整型数组a[1000],已经按从小到大顺序排好。现输入一个数x,请编写一个函数,将该数插入到数组中,并使数组仍然保持从小到大有序。
要求:不得使用排序函数,尽量提高效率。
【样例输入输出】
输入:
5
1 3 4 7 10
输出:
1 3 4 5 7 10
#include <stdio.h>
int main() {
int a[1001], n, i, j, x;
scanf("%d", &n); //读取数组的长度n
scanf("%d", &x); //读取需要插入的元素x
for (i = 0; i < n; i++) { //n
scanf("%d", &a[i]); //输入已经排好顺序的数组元素
}
// 从后往前遍历数组,将大于等于x的元素后移一位,直到找到第一个小于等于x的元素
for (i = n - 1; i >= 0 && a[i] > x; i--) {
a[i + 1] = a[i];
}
// 将x插入到该位置
a[i + 1] = x;
for (i = 0; i < n + 1; i++) { //n+1
printf("%d ", a[i]); //打印数组,此时元素个数多了一个
}
return 0;
}
2.计算及格率和优秀率
【问题描述】
小蓝给学生们组织了一场考试,卷面总分为100分,每个学生的得分都是一个0到100的整数。
如果得分至少是60分,则称为及格。如果得分至少为85分,则称为优秀。
请计算及格率和优秀率,用百分数表示,百分号前的部分四舍五入保留整数。
【输入格式】
输入的第一行包含一个整数n,表示考试人数。接下来n行,每行包含一个0至100的整数,
表示一个学生的得分。
【输出格式】
输出两行,每行一个百分数,分别表示及格率和优秀率。
百分号前的部分四舍五入保留整数。
//C 解法
#include <stdio.h>
#include <math.h>
int main()
{
int n;
scanf("%d", &n);
int total_score = 0; // 总分
int pass_count = 0; // 及格人数
int excellent_count = 0; // 优秀人数
for (int i = 0; i < n; i++)
{
int score;
scanf("%d", &score);
total_score += score;
if (score >= 60)
{
pass_count++;
if (score >= 85)
{
excellent_count++;
}
}
}
double pass_rate = (double)pass_count / n * 100; // 计算及格率
double excellent_rate = (double)excellent_count / n * 100; // 计算优秀率
// 输出结果
// 对于四舍五入保留整数位的输出,我们将double类型的结果强制类型转换为int类型,
// 并使用printf函数来输出带有百分号的整数,它的格式是:%d%%。
printf("%d%%\n", (int)(round(pass_rate))); // 四舍五入保留整数位输出
printf("%d%%\n", (int)(round(excellent_rate))); // 四舍五入保留整数位输出
//C语言中没有double类型的round函数,我们需要使用math.h头文件中的函数来进行四舍五入。
return 0;
}
//C++ 解法
#include <iostream>
#include <iomanip> // 用于输出保留小数点后若干位的数据
#include <cmath> // 用于四舍五入函数round
using namespace std;
int main()
{
int n;
cin >> n;
int total_score = 0; // 总分
int pass_count = 0; // 及格人数
int excellent_count = 0; // 优秀人数
for (int i = 0; i < n; i++)
{
int score;
cin >> score; //输入没行的分数
total_score += score; //每行分数相加
if (score >= 60)
{
pass_count++; //及格人数
if (score >= 85)
{
excellent_count++; //优秀人数
}
}
}
//除法运算可能导致小数点后数据丢失,所以我们使用static_cast来将int类型转换为double类型
double pass_rate = static_cast<double>(pass_count) / n * 100; // 计算及格率
double excellent_rate = static_cast<double>(excellent_count) / n * 100; // 计算优秀率
// 输出结果
cout << round(pass_rate) << "%" << endl;
cout << round(excellent_rate) << "%" << endl;
//可以使用cmath头文件中的round函数对数据进行四舍五入处理。
return 0;
}
3.区间K大数查询
【问题描述】
/*给定一个序列,每次询问序列中第l个数到第r个数中第K大的数是哪个。
输入格式
输入描述:
第一行包含一个数n,表示序列长度。第二行包含n个正整数,表示给定的序列。
第三个包含一个正整数m,表示询问个数。
接下来m行,每行三个数l,r,K,表示询问序列从左往右第l个数到第r个数中,从大往小第K大的数是哪个。序列元素从1开始标号。
输入样例:
5
1 2 3 4 5
2
1 5 2
2 3 2
输出格式输出描述:
总共输出m行,每行一个数,表示询问的答案。
输出样例:
4
2保证k<=(r-l+1),序列中的数<=106。
*/
#include <stdio.h>
void bubble_sort(int a[], int n) //冒泡排序 顺序为从大到小排列
{
int i,j,temp;
for(j=0;j<n-1;j++)
{
for(i=0;i<n-1-j;i++)
{
if(a[i]<a[i+1])
{
temp=a[i];
a[i]=a[i+1];
a[i+1]=temp;
}
}
}
}
int main() {
int n,m,l,r,k;
int i,j; //用于循环
scanf("%d",&n); //输入n值,表示序列长度
int a[n],b[n]; //a[n]为原始序列,b[n]为备份序列,用于排序操作
for(i=0;i<n;i++)
{
scanf("%d",&a[i]);
} //输入一串序列
scanf("%d",&m); //输入询问个数m;
for(i=0;i<m;i++)
{
int num=0;
scanf("%d%d%d",&l,&r,&k); //输入l,r、k的值 ,l为询问起始位置,r为询问结束位置,k为询问区间内第k大的数
for(j=l-1;j<r;j++)
{
b[num++]=a[j];
} //将需要询问的区间取出备份到b[]序列
bubble_sort(b,num);
printf("%d\n",b[k-1]); //直接输出第k大的数,注意:第一大的数为b[0],所以用 k-1;
}
return 0;
}
4.日期读取混乱问题
【问题描述】
小明正在整理一批历史文献。这些历史文献中出现了很多日期。小明知道这些日期都在1960年1月1日至2059年12月31日。
令小明头疼的是,这些日期采用的格式非常不统一,有采用年/月/日的,有采用月/日/年的,还有采用日/月/年的。
更加麻烦的是,年份也都省略了前两位,使得文献上的一个日期,存在很多可能的日期与其对应。比如02/03/04,
可能是2002年03月04日、2004年02月03日或2004年03月02日。\n给出一个文献上的日期,你能帮助小明判断有哪些可能的日期对其对应吗?
【输入描述】
—个日期,格式是\"AA/BB/CC\"(0≤A,B,C≤9)。
【输出描述】
输出若干个不相同的日期,每个日期一行,格式是\"yyyy—MM —dd\"。多个日期按从早到晚排列。
//学会自己理解代码逻辑喔
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <cmath>
using namespace std;
int days[13]={0,31,28,31,30,31,30,31,31,30,31,30,31};
bool check(int year,int month,int day){
if(month==0||month>12)return false;
if(day==0)return false;
if(month!=2){
if(day>days[month])return false;
}else{
int leap=(year%4==0&&year%100!=0)||(year%400==0);
if(day>28+leap)return false;
}
return true;
}
int main(){
int a,b,c;
scanf("%d/%d/%d",&a,&b,&c);
for(int i=19600101;i<20591231;i++){
int year=i/10000;
int month=i/100%100;
int day=i%100;
if(check(year,month,day)){
if(year%100==a&&month==b&&day==c||month==a&&day==b&&year%100==c||day==a&&month==b&&year%100==c)
printf("%d-%02d-%02d\n",year,month,day);
}
}
return 0;
}
5.分巧克力
【问题描述】
儿童节那天有K位小朋友到小明家做客。小明拿出了珍藏的巧克力招待小朋友们。
小明一共有N块巧克力,其中第i块是H;× Wi的方格组成的长方形。为了公平起见,
小明需要从这N块巧克力中切出K块巧克力分给小朋友们。切出的巧克力需要满足:
1.形状是正方形,边长是整数;
2.大小相同;
例如一块6x5的巧克力可以切出6块2x2的巧克力或者2块3x3的巧克力。
当然小朋友们都希望得到的巧克力尽可能大,你能帮小明计算出最大的边长是多少么?
【输入描述】
第一行包含两个整数N, K (1≤N,K ≤105)。
以下N行每行包含两个整数H,Wi (1 ≤H, W;≤105)。
输入保证每位小朋友至少能获得一块1x1的巧克力。
【输出描述】
输出切出的正方形巧克力最大可能的边长。
#include <iostream>
using namespace std;
int L[100005];
int W[100005];
int main(){
//1. 读入 N 和 K,N 表示物品个数,K 表示每个物品至少可以切分成的份数。
//2. 分别读入 N 个物品的长度 L[i] 和宽度 W[i],存储到数组 L 和 W 中。
//3. 声明变量 i 初始值为 10000,用于表示当前可切分的最大长度。
int N,K;
cin>>N>>K;
for(int i=1;i<=N;i++)
cin>>L[i]>>W[i];
int i=10000;
while(true){
int sum=0,num1,num2;
for(int j=1;j<=N;j++){
num1=L[j]/i;
num2=W[j]/i;
sum+=num1*num2;
/*
对于第 j 个物品,先将其长度 L[j]、宽度 W[j] 分别除以 i 获取到能够切割成的
数量 num1 和 num2,再将 num1 和 num2 乘起来得到该物品在 i 长度下最多可以切割成的块数。
最后将每个物品能够 切割成的块数相加,得到总共可以切割成多少块,用 sum 变量进行累加,
得到所有物品能够切割成的总块数。
*/
}
if(sum>=K){
break;
}
//如果总数量 sum 大于等于 K,则说明当前长度 i 是符合要求的,
//可以跳出 while 循环;否则,将 i 的值减 1,继续进行二分查找。
i--;
}
cout<<i;
return 0;
}
持续分享......