c++练习的一些基础总结

天梯赛练习总结

字节转换

1mb=1024kb=1024*1024字节

1字节==8位

R函数一个cout输出多行数据

在这里插入图片描述

数组初始化函数memset

memset(a,0/-1,sizeof(a))

重点sizeof(a),不能用数字,如:memset(a,0,80)

原因是这是地址之间的变化,,,

int数组只能初始化为0或-1;

字符型数组可以初始化为任何字符,如:memset(a,‘r’,sizeof(a));

如果字符型数组选择数字结尾,如memset(a,‘5’,2)

表示只会有初始化后的长度2个


数字转字符串

在这里插入图片描述

字符串转数字

有两种方法:

在这里插入图片描述
在这里插入图片描述

求数字的每一位

while(c>0){
			b=c%10;
			c/=10;
			a[b]--;
			cout<<b<<" ";
		}
		

大数输出

数组思路

用数组存储n以前的每一位,每一位的是个位,而存储n的那一位不限制;为int型


例如A=1, N=3时,S=1+11+111=123。

#include<bits/stdc++.h>
using namespace std;

int main(void){
    int b,n;
    cin>>b>>n;
    int a[n];
    int t=0;
    if(n==0){
    	cout<<"0";
    	return 0;
	}
	  //重点
    for(int i=n;i>1;i--){
    	a[i]=i*b+t;//从n开始,个位 
    	t=a[i]/10;//进位的数 
    	a[i]%=10;//每一位的数 
    	
	}
	a[1]=b+t;//可以大于>10 
	
	for(int i=1;i<=n;i++)//输出方式
	cout<<a[i]; 
    
}

连通性的计算

7-5 红色警报 (25 分)

战争中保持各个城市间的连通性非常重要。本题要求你编写一个报警程序,当失去一个城市导致国家被分裂为多个无法连通的区域时,就发出红色警报。注意:若该国本来就不完全连通,是分裂的k个区域,而失去一个城市并不改变其他城市之间的连通性,则不要发出警报。

#include<bits/stdc++.h>
using namespace std;

int vis[555]={0},a[555][555]={0};
int n,m;

void dfs(int x){
	vis[x]=1;
	for(int i=0;i<n;i++){
		if(!vis[i]&&a[x][i]){
			dfs(i);
		}
	}
}

int ltx(){//连通性
	memset(vis,0,sizeof(vis));
	int sum=0;
	for(int i=0;i<n;i++){
		if(!vis[i]){
			dfs(i);
			sum++;
		}
	}
	return sum;
}

int main(){
	cin>>n>>m;
	while(m--){
		int b,c;
		cin>>b>>c;
		a[b][c]=a[c][b]=1;
	}
	int d1,d2;
	d1=ltx();
	int k;
	cin>>k;
	for(int j=0;j<k;j++){
		int q;
		cin>>q;
		for(int i=0;i<n;i++){
			if(a[q][i]==1){
				a[q][i]=a[i][q]=0;
			}
		}
		d2=ltx();
		//cout<<d1<<d2;
		if(d2>d1+1){
			printf("Red Alert: City %d is lost!\n",q);
		}else{
			printf("City %d is lost.\n",q);
		}
		d1=d2;
	}
	if(k==n)
	cout<<"Game Over.";
	
	
} 

多行字符串统计并排序

7-9 清点代码库 (25 分)

上图转自新浪微博:“阿里代码库有几亿行代码,但其中有很多功能重复的代码,比如单单快排就被重写了几百遍。请设计一个程序,能够将代码库中所有功能重复的代码找出。各位大佬有啥想法,我当时就懵了,然后就挂了。。。”

这里我们把问题简化一下:首先假设两个功能模块如果接受同样的输入,总是给出同样的输出,则它们就是功能重复的;其次我们把每个模块的输出都简化为一个整数(在 int 范围内)。于是我们可以设计一系列输入,检查所有功能模块的对应输出,从而查出功能重复的代码。你的任务就是设计并实现这个简化问题的解决方案。

#include<bits/stdc++.h>
using namespace std;
struct node{
	vector<int> vc;
	int cnt;
};
vector<node>ans;
vector<int> vd;
map<vector<int>,int>mp;
bool cmp(node a,node b){
	if(a.cnt == b.cnt) return a.vc < b.vc;
	return a.cnt > b.cnt;
}
int main(){
	int n , m;
	cin >> n >> m;
	for(int i = 1; i <= n ;i++){
		vd.clear();
		for(int j = 1; j <= m ; j++){
			int x;
			cin >> x;
			vd.push_back(x);
		}
		mp[vd]++;
	}
	cout << mp.size() << '\n';
	for(auto it:mp){
		ans.push_back({it.first,it.second});
	}
	sort(ans.begin(),ans.end(),cmp);
	for(auto it:ans){
		cout << it.cnt;
		for(auto id:it.vc){
			cout << " " << id;
		}
		cout << '\n';
	}
}

进制转换

7-3 5001 特殊的四位数

找出并输出所有小于等于n的4位数(十进制数)中具有如下属性的数:四位数字之和等于其十六进制形式各位数字之和,也等于其十二进制形式各位数字之和。
例如:十进制数2991,其四位数字之和2+9+9+1 = 21。由于2991 = 1 * 1728 + 8 * 144 + 9 * 12 + 3,其十二进制形式为1893(12), 其各位数字之和也为21。但是它的十六进制形式为BAF(16),其各位数字之和等于11+10+15 = 36。因此你的程序要舍去2991这个数据。
下一个数2992,其十进制、十二进制、十六进制形式各位数字之和均为22,因此2992符合要求,应该输出来。(只考虑4位数,2992是第一个符合要求的数)

10进制转其他都是:

%进制,除/进制,即可

其他转10进制:

乘*进制的n次方(n为数的位置,从0开始)

#include<iostream>
using namespace std;

int f10(int a){
	int s=0;
	while(1){
		if(a<=0) break;
		s+=a%10;
		a/=10;
	}
	return s;
}

int f12(int a){
	int s=0;
	while(1){
		if(a<=0) break;
		s+=a%12;
		a/=12;
	}
	return s;
}

int f16(int a){
	int s=0;
	while(1){
		if(a<=0) break;
		s+=a%16;
		a/=16;
	}
	return s;
}

int main(){
	int x,fl=1;
	while(cin>>x){
		for(int i=1000;i<=x;i++){
			if(f10(i)==f12(i)&&f10(i)==f16(i)){
				cout<<i<<endl;
				fl=0;
			}
			
		}
		if(fl) cout<<"0"<<endl;
		
	}
	
	
	
}

字典序排序

7-5 树种统计 (25 分)

随着卫星成像技术的应用,自然资源研究机构可以识别每一棵树的种类。请编写程序帮助研究人员统计每种树的数量,计算每种树占总数的百分比。

原理:

a,ab,b,aa

排序:a,aa,ab,b

#include<iostream>
#include<map>
#include<algorithm>
using namespace std;
 
struct nd{
	string s;
	int a=0;
}b[199999];

int cmp(nd x,nd y){
	return x.s<y.s;
}

map<string,int> m;

int main() {
	int n;
	cin>>n;
	getchar();
	for(int i=0;i<n;i++){
		string t;
		getline(cin,t);
		m[t]++;
	}
	int j=0;
	for(auto it=m.begin();it!=m.end();it++){
		b[j].s=it->first;
		b[j++].a=it->second;
	}
	sort(b,b+j,cmp);
	for(int i=0;i<j;i++){
		cout<<b[i].s;
        double e=1.0*b[i].a/n*100;
        printf(" %.4lf%%",e);
            cout<<endl;
	}
	
}

map去重,结构体排序

#include<iostream>
#include<map>
#include<algorithm>
using namespace std;
 
struct nd{
	string s;
	int a;
}b[19999];

int cmp(nd x,nd y){
	return x.s<y.s;
}

map<string,int> m;

int main() {
	int n,s=0,q=0;
	cin>>n;
	getchar();
	for(int i=0;i<n;i++){
		string t;
		getline(cin,t);
		m[t]++;
	}
	int j=0;
	for(auto it=m.begin();it!=m.end();it++){
		b[j].s=it->first;
		b[j].a=it->second;
	}
	sort(b,b+j,cmp);
	for(int i=0;i<j;i++){
		cout<<b[i].s<<endl;
	}
	
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值