ZISUOJ 高级语言程序设计实训-基础A

该博客以简洁的C++代码形式给出一系列算法题的思路与参考题解。题目涵盖比较大小、字符矩形绘制、最大公约数求解等。思路涉及if条件判断、循环、辗转相除法等,部分题还给出多种解题方法,如逆序输出可用逆序遍历、栈等方法。

说明:

        我这次代码以尽可能简洁的C++代码形式给出。

题目列表:

问题 A: 比较大小 

 

思路:

        一道简单的if条件判断题。

参考题解:

#include <bits/stdc++.h>
#define endl '\n'
using namespace std;
using ll = long long;
using ull = unsigned long long;
using pii = pair<int,int>;
constexpr int N = 1e2+5,M = 1e2+5,MOD = 1e9+7,INF = 0x3f3f3f3f,P = 131;
void solve(){
	int a,b;cin >> a >> b;
	if(a>b) cout << "Bigger\n";
	else if(a<b) cout << "Smaller\n";
	else cout << "Equal\n";
}
int main(){
	ios::sync_with_stdio(false),cin.tie(nullptr),cout.tie(nullptr);
	int T = 1;
	cin >> T;
	while(T--) solve();
	return 0;
}

问题 B: 一个@字符矩形

思路:

        简单循环考察题。

参考题解:

#include <bits/stdc++.h>
#define endl '\n'
using namespace std;
using ll = long long;
using ull = unsigned long long;
using pii = pair<int,int>;
constexpr int N = 1e2+5,M = 1e2+5,MOD = 1e9+7,INF = 0x3f3f3f3f,P = 131;
void solve(){
	int n;cin >> n;
	for(int i = 1;i<=n;i++){
		for(int j = 1;j<=20;j++) cout << '@';
		cout << '\n';
	}
}
int main(){
	ios::sync_with_stdio(false),cin.tie(nullptr),cout.tie(nullptr);
	int T = 1;
//	cin >> T;
	while(T--) solve();
	return 0;
}

问题 C: 最大公约数和最小公倍数

思路:

        考察辗转相除法(也叫欧几里得算法)求最大公约数。另外,最大公倍数=两个数的乘积除以他们的最大公约数。我下面直接用STL的__gcd()函数了,就不自己写了gcd()函数了

参考题解:

#include <bits/stdc++.h>
#define endl '\n'
using namespace std;
using ll = long long;
using ull = unsigned long long;
using pii = pair<int,int>;
constexpr int N = 1e2+5,M = 1e2+5,MOD = 1e9+7,INF = 0x3f3f3f3f,P = 131;
void solve(){
	int a,b;cin >> a >> b;
	cout << __gcd(a,b) << ' ' << a/__gcd(a,b)*b << '\n';
}
int main(){
	ios::sync_with_stdio(false),cin.tie(nullptr),cout.tie(nullptr);
	int T = 1;
//	cin >> T;
	while(T--) solve();
	return 0;
}

问题 D: 水仙花数

思路:

        根据题意,我们从100到999遍历找一遍输出即可。

参考题解:

#include <bits/stdc++.h>
#define endl '\n'
using namespace std;
using ll = long long;
using ull = unsigned long long;
using pii = pair<int,int>;
constexpr int N = 1e2+5,M = 1e2+5,MOD = 1e9+7,INF = 0x3f3f3f3f,P = 131;

void solve(){
	 for(int i = 100;i<1000;i++){
	 	int a=i%10,b=i/10%10,c=i/100;
	 	if(i==pow(a,3)+pow(b,3)+pow(c,3)) cout << i << '\n';
	 }
}
int main(){
	ios::sync_with_stdio(false),cin.tie(nullptr),cout.tie(nullptr);
	int T = 1;
//	cin >> T;
	while(T--) solve();
	return 0;
}

问题 E: 第N次落地

思路:

        我们发现到N次落地会经过N次下落,N-1次上升,计算最后的经过路径长度要注意。

参考题解:

#include <bits/stdc++.h>
#define endl '\n'
using namespace std;
using ll = long long;
using ull = unsigned long long;
using pii = pair<int,int>;
constexpr int N = 1e2+5,M = 1e2+5,MOD = 1e9+7,INF = 0x3f3f3f3f,P = 131;

void solve(){
	 double height;
	 int n;
	 cin >> height >> n;
	 double sum = 0;
	 for(int i = 1;i<=n;i++){
	 	sum+=height;//下落
	 	height/=2;
	 	sum+=height;//上升
	 }
	 sum-=height;//多加了一次上升的距离,因此要减掉
	 cout << fixed << setprecision(2) << height << ' ' << sum << '\n';
}
int main(){
	ios::sync_with_stdio(false),cin.tie(nullptr),cout.tie(nullptr);
	int T = 1;
//	cin >> T;
	while(T--) solve();
	return 0;
}

问题 F: 画字符三角形

思路:

        考察简单的二重循环。

参考题解:

#include <bits/stdc++.h>
#define endl '\n'
using namespace std;
using ll = long long;
using ull = unsigned long long;
using pii = pair<int,int>;
constexpr int N = 1e2+5,M = 1e2+5,MOD = 1e9+7,INF = 0x3f3f3f3f,P = 131;
void solve(){
	 char c;cin >> c;
	 for(int i = 1;i<=7;i++){
	 	for(int j = 1;j<=7-i;j++) cout << ' ';
	 	for(int j = 1;j<=2*i-1;j++) cout << c;
	 	cout << '\n'; 
	 }
}
int main(){
	ios::sync_with_stdio(false),cin.tie(nullptr),cout.tie(nullptr);
	int T = 1;
//	cin >> T;
	while(T--) solve();
	return 0;
}

问题 G: 冒泡法排序

思路:

        你让我冒泡我就冒泡?直接sort()它不香嘛?(滑稽)

参考题解1(直接sort):

#include <bits/stdc++.h>
#define endl '\n'
using namespace std;
using ll = long long;
using ull = unsigned long long;
using pii = pair<int,int>;
constexpr int N = 1e2+5,M = 1e2+5,MOD = 1e9+7,INF = 0x3f3f3f3f,P = 131;
int a[11];
void solve(){
	for(int i = 1;i<=10;i++) cin >> a[i];
	sort(a+1,a+1+10);
	for(int i = 1;i<=10;i++) cout << a[i] << '\n';
}
int main(){
	ios::sync_with_stdio(false),cin.tie(nullptr),cout.tie(nullptr);
	int T = 1;
//	cin >> T;
	while(T--) solve();
	return 0;
}

参考题解2(冒泡排序):

#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using pii = pair<int,int>;
constexpr int N=1e5+5,M=1e2+5,INF=0x3f3f3f3f,MOD=1e9+7,P=131;
int a[11];
void solve(){
	for(int i = 1;i<=10;i++) cin >> a[i];
	for(int i = 1;i<=10-1;i++){
		for(int j = 1;j<=10-i;j++){
			if(a[j]>a[j+1]){
				int tmp = a[j];
				a[j]=a[j+1];
				a[j+1]=tmp;
			}
		}
	}
	for(int i = 1;i<=10;i++) cout << a[i] << '\n';
}
int main() {
	ios::sync_with_stdio(false),cin.tie(nullptr),cout.tie(nullptr);
	int T = 1;
//	cin >> T;
	while(T--) solve();
	return 0;
}

问题 H: 矩阵对角线元素之和

思路:

        主对角线之和:行和列相等的时候的值之和

        副对角线之和:行加列等于n+1的值之和

参考题解:

#include <bits/stdc++.h>
#define endl '\n'
using namespace std;
using ll = long long;
using ull = unsigned long long;
using pii = pair<int,int>;
constexpr int N = 1e2+5,M = 1e2+5,MOD = 1e9+7,INF = 0x3f3f3f3f,P = 131;
int a[4][4];
void solve(){
	for(int i = 1;i<=3;i++){
		for(int j = 1;j<=3;j++){
			cin >> a[i][j];
		}
	}
	int ans1=0,ans2=0;//ans1是主对角线之和,ans2是副对角线之和
	for(int i = 1;i<=3;i++){
		for(int j = 1;j<=3;j++){
			if(i==j) ans1+=a[i][j];
			if(i+j==4) ans2+=a[i][j];
		}
	}
	cout << ans1 << ' ' << ans2 << '\n';
}
int main(){
	ios::sync_with_stdio(false),cin.tie(nullptr),cout.tie(nullptr);
	int T = 1;
//	cin >> T;
	while(T--) solve();
	return 0;
}

问题 I: 逆序输出 

思路:

        方法很多:

                1.直接逆序遍历

                2.用栈(栈是先进后出的)做

                3.反转数组顺序遍历

参考题解1:

#include <bits/stdc++.h>
#define endl '\n'
using namespace std;
using ll = long long;
using ull = unsigned long long;
using pii = pair<int,int>;
constexpr int N = 1e2+5,M = 1e2+5,MOD = 1e9+7,INF = 0x3f3f3f3f,P = 131;
int a[11];
void solve(){
	for(int i = 1;i<=10;i++) cin >> a[i];
	for(int i = 10;i>=1;i--) cout << a[i] << " \n"[i==1];
}
int main(){
	ios::sync_with_stdio(false),cin.tie(nullptr),cout.tie(nullptr);
	int T = 1;
//	cin >> T;
	while(T--) solve();
	return 0;
}

参考题解2:

#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using pii = pair<int,int>;
constexpr int N=1e5+5,M=1e2+5,INF=0x3f3f3f3f,MOD=1e9+7,P=131;
stack<int> stk;
void solve(){
	for(int i = 1;i<=10;i++){
		int n;cin >> n;
		stk.push(n);
	}
	while(stk.size()){
		int t = stk.top();
		cout << t << ' ';
		stk.pop();
		if(stk.empty()) cout << '\n'; 
	}
}
int main() {
	ios::sync_with_stdio(false),cin.tie(nullptr),cout.tie(nullptr);
	int T = 1;
//	cin >> T;
	while(T--) solve();
	return 0;
}

参考题解3:

#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using pii = pair<int,int>;
constexpr int N=1e5+5,M=1e2+5,INF=0x3f3f3f3f,MOD=1e9+7,P=131;
vector<int> a; 
void solve(){
	for(int i = 1;i<=10;i++){
		int n;cin >> n;
		a.push_back(n);
	}
	reverse(a.begin(),a.end());
	for(int i = 0;i<a.size();i++) cout << a[i] << " \n"[i==a.size()-1];
}
int main() {
	ios::sync_with_stdio(false),cin.tie(nullptr),cout.tie(nullptr);
	int T = 1;
//	cin >> T;
	while(T--) solve();
	return 0;
}

问题 J: 字符串翻转

 

思路:

        用string存,直接用reverse()函数反转后输出即可。

参考题解:

#include <bits/stdc++.h>
#define endl '\n'
using namespace std;
using ll = long long;
using ull = unsigned long long;
using pii = pair<int,int>;
constexpr int N = 1e2+5,M = 1e2+5,MOD = 1e9+7,INF = 0x3f3f3f3f,P = 131;
string s;
void solve(){
	cin >> s;
	reverse(s.begin(),s.end());
	cout << s << '\n';
}
int main(){
	ios::sync_with_stdio(false),cin.tie(nullptr),cout.tie(nullptr);
	int T = 1;
//	cin >> T;
	while(T--) solve();
	return 0;
}

问题 K: 菲波那契数

思路:

        使用循环进行递推后输出。

参考题解:

#include <bits/stdc++.h>
#define endl '\n'
using namespace std;
using ll = long long;
using ull = unsigned long long;
using pii = pair<int,int>;
constexpr int N = 1e2+5,M = 1e2+5,MOD = 1e9+7,INF = 0x3f3f3f3f,P = 131;
int n;
int f[55];
void solve(){
	cin >> n;
	f[0]=0,f[1]=1;
	for(int i = 2;i<=n;i++){
		f[i]=f[i-1]+f[i-2];
	}
	cout << f[n] << '\n';
}
int main(){
	ios::sync_with_stdio(false),cin.tie(nullptr),cout.tie(nullptr);
	int T = 1;
//	cin >> T;
	while(T--) solve();
	return 0;
}

问题 L: 寻找幸运数

思路:

        每组数据if判断一下三个数即可。

参考题解:

#include <bits/stdc++.h>
#define endl '\n'
using namespace std;
using ll = long long;
using ull = unsigned long long;
using pii = pair<int,int>;
constexpr int N = 1e2+5,M = 1e2+5,MOD = 1e9+7,INF = 0x3f3f3f3f,P = 131;
int a,b,c;
void solve(){
	while(cin >> a >> b >> c){
		if(a==-1&&b==-1&&c==-1) break;
		if(a<=168){
			cout << "CRASH " << a << '\n';
			continue;
		}
		if(b<=168){
			cout << "CRASH " << b << '\n';
			continue;
		}
		if(c<=168){
			cout << "CRASH " << c << '\n';
			continue;
		}
		cout << "NO CRASH\n";
	}
}
int main(){
	ios::sync_with_stdio(false),cin.tie(nullptr),cout.tie(nullptr);
	int T = 1;
//	cin >> T;
	while(T--) solve();
	return 0;
}

问题 M: 求等差数列的和

思路:

        使用等差数列求和公式时间复杂度直接是O(1)。

参考题解:

#include <bits/stdc++.h>
#define endl '\n'
using namespace std;
using ll = long long;
using ull = unsigned long long;
using pii = pair<int,int>;
constexpr int N = 1e2+5,M = 1e2+5,MOD = 1e9+7,INF = 0x3f3f3f3f,P = 131;
ll a,b,c;
void solve(){
	while(cin >> a >> b >> c){
		if(a==0&&b==0&&c==0) break;
		ll sum = (a+b)*((b-a)/c+1)/2;
		cout << sum << '\n';
	}
}
int main(){
	ios::sync_with_stdio(false),cin.tie(nullptr),cout.tie(nullptr);
	int T = 1;
//	cin >> T;
	while(T--) solve();
	return 0;
}

问题 N: 字母转换

思路:

        遍历所有行,如果是小写字符则转换成大写,如果是大写字符则转换成小写。

参考题解:

#include <bits/stdc++.h>
#define endl '\n'
using namespace std;
using ll = long long;
using ull = unsigned long long;
using pii = pair<int,int>;
constexpr int N = 1e2+5,M = 1e2+5,MOD = 1e9+7,INF = 0x3f3f3f3f,P = 131;
string s;
void solve(){
	while(getline(cin,s)){
		for(int i = 0;i<s.size();i++){
			if(s[i]>='a'&&s[i]<='z'){
				cout << (char)('A'+s[i]-'a');
			}else if(s[i]>='A'&&s[i]<='Z'){
				cout << (char)('a'+s[i]-'A');
			}else cout << s[i];
		}
		cout << '\n';
	}
}
int main(){
	ios::sync_with_stdio(false),cin.tie(nullptr),cout.tie(nullptr);
	int T = 1;
//	cin >> T;
	while(T--) solve();
	return 0;
}

问题 O: 计算矩形面积

思路:

        注意提示,暗示(明示)我们要用long long来算,并且计算好后还需要排序才能输出。

参考题解:

#include <bits/stdc++.h>
#define endl '\n'
using namespace std;
using ll = long long;
using ull = unsigned long long;
using pii = pair<int,int>;
constexpr int N = 1e2+5,M = 1e2+5,MOD = 1e9+7,INF = 0x3f3f3f3f,P = 131;
ll a,b,c,d;
ll t[105];
void solve(){
	int idx = 0;
	while(cin >> a >> b >> c >> d){
		t[idx]=abs(a-c)*abs(b-d);
		idx++;
	}
	sort(t,t+idx);
	for(int i = 0;i<idx;i++) cout << t[i] << '\n';
}
int main(){
	ios::sync_with_stdio(false),cin.tie(nullptr),cout.tie(nullptr);
	int T = 1;
//	cin >> T;
	while(T--) solve();
	return 0;
}

问题 P: 对称文

思路:

        这个题,没啥特别好的思路,只能读入一行,把所有字符都转成小写字符,然后把字符串长度分奇偶从中间往两边遍历判断是否对称,特别地,四个左右括号要特殊判断。

参考题解:

#include <bits/stdc++.h>
#define endl '\n'
using namespace std;
using ll = long long;
using ull = unsigned long long;
using pii = pair<int,int>;
constexpr int N = 1e2+5,M = 1e2+5,MOD = 1e9+7,INF = 0x3f3f3f3f,P = 131;
string s;
void solve(){
	while(getline(cin,s)){
		if(s=="000000") break;
		for(int i = 0;i<s.size();i++){
			s[i]=tolower(s[i]);
		}
		int flag = 0;
		int len = s.size();
		if(len%2==1){
			for(int i = 0;i<=len/2;i++){
				if(s[len/2+i]!=s[len/2-i]){
					if(s[len/2+i]==']'&&s[len/2-i]=='[') continue;
					else if(s[len/2+i]==')'&&s[len/2-i]=='(') continue;
					else if(s[len/2+i]=='>'&&s[len/2-i]=='<') continue;
					else if(s[len/2+i]=='}'&&s[len/2-i]=='{') continue;
					flag = 1;
					break;
				}
			}
		}else{
			for(int i = 0;i<len/2;i++){
				if(s[len/2+i]!=s[len/2-1-i]){
					if(s[len/2+i]==']'&&s[len/2-1-i]=='[') continue;
					else if(s[len/2+i]==')'&&s[len/2-1-i]=='(') continue;
					else if(s[len/2+i]=='>'&&s[len/2-1-i]=='<') continue;
					else if(s[len/2+i]=='}'&&s[len/2-1-i]=='{') continue;
					flag = 1;
					break;
				}
			}
		}
		if(flag) cout << "Not symmetry\n";
		else cout << "Symmetry\n";
	}
}
int main(){
	ios::sync_with_stdio(false),cin.tie(nullptr),cout.tie(nullptr);
	int T = 1;
//	cin >> T;
	while(T--) solve();
	return 0;
}

问题 Q: 判断数字

思路:

        遍历判断即可。

参考题解:

#include <bits/stdc++.h>
#define endl '\n'
using namespace std;
using ll = long long;
using ull = unsigned long long;
using pii = pair<int,int>;
constexpr int N = 1e2+5,M = 1e2+5,MOD = 1e9+7,INF = 0x3f3f3f3f,P = 131;
string s;
void solve(){
	while(getline(cin,s)){
		int flag = 0;
		for(int i = 0;i<s.size();i++){
			if(s[i]<'0'||s[i]>'9'){
				flag = 1;
				break;
			}
		}
		if(flag){
			cout << "No\n";
		}else{
			cout << "Yes\n";
		}
	}
}
int main(){
	ios::sync_with_stdio(false),cin.tie(nullptr),cout.tie(nullptr);
	int T = 1;
//	cin >> T;
	while(T--) solve();
	return 0;
}

问题 R: 美丽的数

思路:

        根据要求排序后输出最美丽的数即可。

参考题解:

#include <bits/stdc++.h>
#define endl '\n'
using namespace std;
using ll = long long;
using ull = unsigned long long;
using pii = pair<int,int>;
constexpr int N = 1e5+5,M = 1e2+5,MOD = 1e9+7,INF = 0x3f3f3f3f,P = 131;
int n;
pii a[N];
int primes[]={2,3,5,7};
bool cmp(pii p1,pii p2){
	if(p1.first!=p2.first) return p1.first>p2.first;
	else return p1.second<p2.second;
	
}
void solve(){
	while(cin >> n){
		if(n==0) break;
		int tmp;
		for(int i = 1;i<=n;i++){
			int t;cin >> t;
			tmp = t;
			int cnt = 0;
			while(tmp){
				for(int i = 0;i<4;i++){
					if(tmp%10==primes[i]){
						cnt++;
					}
				}
				tmp/=10;
			}
			a[i]={cnt,t};
		}
		sort(a+1,a+1+n,cmp);
		cout << a[1].second << '\n';
	}
	
}
int main(){
	ios::sync_with_stdio(false),cin.tie(nullptr),cout.tie(nullptr);
	int T = 1;
//	cin >> T;
	while(T--) solve();
	return 0;
}

问题 S: 统计数字

思路:

        循环遍历的时候一边用map记录出现次数,一边累加总和。

参考题解:

#include <bits/stdc++.h>
#define endl '\n'
using namespace std;
using ll = long long;
using ull = unsigned long long;
using pii = pair<int,int>;
constexpr int N = 1e5+5,M = 1e2+5,MOD = 1e9+7,INF = 0x3f3f3f3f,P = 131;
string s;
void solve(){
	cin >> s;
	map<char,int> mp;
	ll sum = 0;
	for(int i = 0;i<s.size();i++){
		mp[s[i]]++;
		sum+=s[i]-'0';
	}
	for(auto &i:mp){
		cout << i.first << ":" << i.second << '\n';
	}
	cout << sum << '\n';
}
int main(){
	ios::sync_with_stdio(false),cin.tie(nullptr),cout.tie(nullptr);
	int T = 1;
	cin >> T;
	while(T--){
		solve();
		if(T!=0) cout << '\n';
	}
	return 0;
}

问题 T: 按长度排序

思路:

        根据题意写结构体或者pair排序输出即可。

参考题解:

#include <bits/stdc++.h>
#define endl '\n'
using namespace std;
using ll = long long;
using ull = unsigned long long;
using pii = pair<int,int>;
constexpr int N = 1e5+5,M = 1e2+5,MOD = 1e9+7,INF = 0x3f3f3f3f,P = 131;
pair<int,string> p[N];
string s;
void solve(){
	int n;
	while(cin >> n,n){
		for(int i = 1;i<=n;i++){
			cin >> s;
			int len = s.size();
			p[i]={len,s};
		}
		sort(p+1,p+1+n,[&](pair<int,string> p1,pair<int,string> p2)->bool{
			if(p1.first!=p2.first) return p1.first<p2.first;
			else return p1.second<p2.second;
		});
		for(int i = 1;i<=n;i++) cout << p[i].second << '\n';
		cout << '\n';
	}
}
int main(){
	ios::sync_with_stdio(false),cin.tie(nullptr),cout.tie(nullptr);
	int T = 1;
//	cin >> T;
	while(T--){
		solve();
	}
	return 0;
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Beau_Will

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

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

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

打赏作者

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

抵扣说明:

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

余额充值