ZISUOJ C语言-综合练习

说明:

博主是ZISU在校学生,刚学C/C++才3个月,为了记录自己的学习过程和分享思路,故写一些博客。当然我的代码许多时候不是最优解,欢迎大家评论留言一起学习。如果有友友想提交这些题试试自己的思路啥的,可以私我,因为外校友友应该是登陆不进咱们的平台的。对于搜索到本博客的同校友友,切勿直接照抄,理解了再自己码字码上去。

题目列表:

 问题 A: 二进制中1的个数

思路:先计算每个数的二进制1的个数,然后循环打擂台找最大的二进制1的个数,再循环找第一个出现跟前面个数相等的下标,输出对应下标的数即可

参考题解:

#include <bits/stdc++.h>
using namespace std;
const int N = 1e2+5;//N=(int)105
struct number{
	int num,num_of_binary_one;//num为数值,num_of_binary_one为该数值对应的含有的二进制1的个数 
}a[N];
int cal_num_of_binary_one(int num1){//计算num1含有的二进制1的个数 
	int count = 0;
	while(num1!=0){
		if(num1%2==1) count++;
		num1/=2;
	}
	return count;
}
int main(){
	//问题 A: 二进制中1的个数
	ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);//要用scanf()和printf()不能使用快读
	int n;cin >> n;
	for(int i = 1;i<=n;i++) cin >> a[i].num;
	//计算数值对应的含有的二进制1的个数
	for(int i = 1;i<=n;i++) a[i].num_of_binary_one = cal_num_of_binary_one(a[i].num);
	int maxone = 0;//maxone找所有数中最多的二进制1的个数 
	for(int i = 1;i<=n;i++) if(a[i].num_of_binary_one > maxone) maxone =  a[i].num_of_binary_one;
	int maxindex = 1;//记录结果的下标 
	//遍历查询,如果找到第一个二进制1的个数跟maxindex相等的记录下它的下标并跳出循环 
	for(int i = 1;i<=n;i++){
		if(a[i].num_of_binary_one == maxone){
			maxindex = i;break;
		}
	}
	cout << a[maxindex].num << '\n';
	return 0;
}

问题 B: 最新版消消乐

 

思路:遍历输入的字符串,有两个重复的字符则只输出一次,其余情况正常输出即可

参考题解:

#include <bits/stdc++.h>
using namespace std;
const int N = 1e2+5;
char s[N]; 
int main(){
	//问题 B: 最新版消消乐
	ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);//要用scanf()和printf()不能使用快读
	cin >> s;
	int i = 0;//i为s的下标
	while(i<strlen(s)){//下标i遍历s 
		if(s[i]==s[i+1]&&i<strlen(s)-1){//如果有两个重复字母,则只输出一次 
			cout << s[i]; 
			i+=2;
		}else{//正常输出 
			cout << s[i];
			i++;
		}
	}
	cout << '\n';
	return 0;
}

问题 C: 组合数

说明:依据题意写一个求组合数C(n,m)的函数计算即可

参考题解:

#include <bits/stdc++.h>
using namespace std;
using ll = unsigned long long;//使用ll代替unsigned long long 
ll factorial(int num){//计算阶乘函数 
	ll res = 1;
	for(int i = 1;i<=num;i++) res*=i;
	return res;
}
ll C(int n,int m){//计算组合数函数 
	return (factorial(n)/factorial(n-m))/factorial(m);
}
int main(){
	//问题 C: 组合数
	ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);//要用scanf()和printf()不能使用快读
	int n,m; 
	while(cin >> n >> m){//没有输入则跳出循环 
		cout << C(n,m) << '\n';//输出所求组合数答案 
	}
	return 0;
}

问题 D: 费马平方和定理

 

 思路:根据定理的说明,先判断该范围内模4余1的数是否为素数,如果为素数再开始暴力寻找对应的平方和

参考题解:

#include <bits/stdc++.h>
using namespace std;
bool is_Prime(int num){//判断是否为素数,为素数则返回true,否则返回false 
	if(num <= 1) return false;
	for(int i = 2;i*i<=num;i++){
		if(num%i==0) return false;
	}
	return true;
}
int main(){
	//问题 D: 费马平方和定理
	ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);//要用scanf()和printf()不能使用快读
	int n;cin >> n;
	for(int i = 5;i<=n;i+=4){//i的步长为4 
		if(is_Prime(i)){//如果为素数,则开始找满足i的费马平方和定理 
			int type = 0;//type为1则表示以及找到i的费马平方和定理的公式了,type为0则表示暂时还没找到 
			for(int j = 1;j*j<=i;j++){
				for(int k = sqrt(i-1);k>=1;k--){
					if(j*j+k*k==i){
						//格式化输出 
						cout << i << '=' << j << "**2+" << k << "**2" << '\n';
						type = 1;
						break;
					}
				}
				if(type) break;//type为1跳出循环 
			}
		}
	} 
	return 0;
}

问题 E: 成绩排名1

说明:开一个student结构体,存放student的学号和总分,使用sort()函数先按照总分从高到低排序,如果总分相同则按照学号从小到大排序,最后输出即可

参考题解:

#include <bits/stdc++.h>
using namespace std;
const int N = 1e4+5;
struct student{
	string number;//学号 
	int score;//总分成绩 
}stu[N];
bool cmp(student stu1,student stu2){
	//按照总分成绩从高到低排序 
	if(stu1.score!=stu2.score) return stu1.score>stu2.score;
	//如果总分成绩相同,则按照学号从小到大排序 
	else return stu1.number<stu2.number;
}
int main(){
	//问题 E: 成绩排名1
	ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);//要用scanf()和printf()不能使用快读
	int n;cin >> n;
	//读入每个学生学号和总分成绩 
	for(int i = 1;i<=n;i++) cin >> stu[i].number >> stu[i].score;
	sort(stu+1,stu+1+n,cmp);//从stu[1]到stu[n]按照cmp规则排序 
	//格式化输出 
	for(int i = 1;i<=n;i++) cout << stu[i].number << ' ' << stu[i].score << '\n';
	return 0;
}

 问题 F: 成绩排名2

 

说明:与上面一题思路同理,计算出每个学生的总成绩并按照总成绩从高到低排序,如果总成绩相同,则按照学号从小到大排序,同时还需要计算出每个学生所有题目中的单题最高成绩,最后按顺序输出学号和单题最高成绩即可。

参考题解:

#include <bits/stdc++.h>
using namespace std;
const int N = 1e4+5;
struct student{
	string number;//学号
	int m,total_score,max_score;//m为做出的题目数,total_score为总分,max_score为单题最高分 
	int score[15];//各个题目的成绩 
}stu[N];
bool cmp(student stu1,student stu2){
	//按照总分成绩从高到低排序 
	if(stu1.total_score!=stu2.total_score) return stu1.total_score>stu2.total_score;
	//如果总分成绩相同,则按照学号从小到大排序 
	else return stu1.number<stu2.number;
}
int main(){
	//问题 E: 成绩排名1
	ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);//要用scanf()和printf()不能使用快读
	int n;cin >> n;
	//读入每个学生学号和总分成绩 
	for(int i = 1;i<=n;i++){
		cin >> stu[i].number >> stu[i].m;
		int sum = 0;//暂存当前数量题目得分的累加和 
		for(int j = 1;j<=stu[i].m;j++){
			cin >> stu[i].score[j];
			sum += stu[i].score[j];
		}
		//赋值该学生的总分,给单题最高分赋初始值 
		stu[i].total_score = sum,stu[i].max_score = 0;
		//打擂台找单题最高分 
		for(int j = 1;j<=stu[i].m;j++) if(stu[i].score[j]>stu[i].max_score) stu[i].max_score = stu[i].score[j];
	}
	sort(stu+1,stu+1+n,cmp);//从stu[1]到stu[n]按照cmp规则排序
	//输出 
	for(int i = 1;i<=n;i++) cout << stu[i].number << ' ' << stu[i].max_score << '\n';
	return 0;
}

问题 G: 纠结的PP

说明:贪心思想,把鞋子按照重量从小到大排序,能拿当前最轻的鞋子就拿最轻的,拿不了就输出结果

参考题解:

#include <bits/stdc++.h>
using namespace std;
const int N = 1e4+5;
const int MAX = 3000;
struct shoes{
	string name;//鞋名 
	int weight;//鞋的重量 
}shoe[N];
bool cmp(shoes shoe1,shoes shoe2){
	//按鞋的重量从小到大排序 
	return shoe1.weight<shoe2.weight;
}
int main(){
	//问题 G: 纠结的PP
	ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);//要用scanf()和printf()不能使用快读
	int n;cin >> n;
	//读鞋的鞋名和鞋的重量 
	for(int i = 1;i<=n;i++) cin >> shoe[i].name >> shoe[i].weight;
	sort(shoe+1,shoe+1+n,cmp);//从shoe[1]到shoe[n]按照cmp规则排序 
	int now_weight = 0,now_num = 0;//now_weight为当前重量,now_num为当前鞋子的双数 
	for(int i = 1;i<=n;i++){//贪心
		//能拿最轻的鞋子就先拿最新的鞋子 
		if(now_weight+shoe[i].weight<=MAX){
			//累加当前重量 
			now_weight += shoe[i].weight;
			//鞋子双数加1 
			now_num++;
		}else break;//拿不了就跳出循环
	}
	if(!now_num) cout << ":(" << '\n';//一双都拿不了输出":(" 
	else cout << now_num << '\n';//能拿几双输出几双 
	return 0;
}

问题 H: 七七七

 

说明:同理,开结构体存放弹幕字符串,弹幕的长度,弹幕含7的个数,然后按照题目描述的要求排序输出即可

参考题解:

#include <bits/stdc++.h>
using namespace std;
const int N = 1e4+5;
struct barrage{
	string str;//弹幕字符串
	int len;//弹幕字符串的长度 
	int num_of_seven;//弹幕中'7'的个数 
}b[N];
int cal_num_of_seven(barrage b){//计算弹幕中'7'的个数 
	int res = 0;
	for(int i = 0;i<b.len;i++) if(b.str[i]=='7') res++;
	return res;
}
bool cmp(barrage b1,barrage b2){
	//包含数字"7"多的排在前面
	if(b1.num_of_seven!=b2.num_of_seven) return b1.num_of_seven>b2.num_of_seven;
	//如果两句弹幕包含一样多的"7",则按照长度从小到大排
	else if(b1.num_of_seven==b2.num_of_seven&&b1.len!=b2.len) return b1.len<b2.len;
	//如果长度仍然一样,则按照字典序大的排在前面
	else return b1.str>b2.str;
}
int main(){
	//问题 H: 七七七
	ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);//要用scanf()和printf()不能使用快读
	int n;cin >> n;
	for(int i = 1;i<=n;i++){
		cin >> b[i].str;//读入弹幕的字符串 
		b[i].len = b[i].str.length();//计算弹幕字符串的长度 
		//计算弹幕字符串中'7'的个数 
		b[i].num_of_seven = cal_num_of_seven(b[i]);
	}
	sort(b+1,b+1+n,cmp);//从b[1]到b[n]按照cmp规则排序
	//输出 
	for(int i = 1;i<=n;i++) cout << b[i].str << '\n';
	return 0;
}

问题 I: 排名次

说明:同理,使用结构体存放姓名和成绩,按照成绩从高到低排序,如果成绩相同,则把名字按照字典顺序排序,输出排序后的结果即可

参考题解:

#include <bits/stdc++.h>
using namespace std;
const int N = 1e3+5;
struct student{
	string name;//学生姓名 
	int score;//学生成绩 
}stu[N];
bool cmp(student stu1,student stu2){
	//按成绩(分数)从高分到低分的顺序排名
	if(stu1.score!=stu2.score) return stu1.score>stu2.score;
	//如果成绩(分数)相同则按姓名进行排序(字典顺序)
	else return stu1.name<stu2.name;
}
int main(){
	//问题 I: 排名次
	ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);//要用scanf()和printf()不能使用快读
	int n;cin >> n;
	//读入学生姓名和分数 
	for(int i = 1;i<=n;i++) cin >> stu[i].name >> stu[i].score;
	sort(stu+1,stu+1+n,cmp);//从stu[1]到stu[n]按照cmp规则排序
	for(int i = 1;i<=n;i++) cout << stu[i].name << ' ' << stu[i].score << '\n'; 
	return 0;
}
  • 17
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Beau_Will

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值