天梯赛练习总结
字节转换
1mb=1024kb=1024*1024字节
1字节==8位
R函数一个cout输出多行数据
数组初始化函数memset
原因是这是地址之间的变化,,,
如果字符型数组选择数字结尾,如memset(a,‘5’,2)
表示只会有初始化后的长度2个
数字转字符串
字符串转数字
有两种方法:
求数字的每一位
while(c>0){
b=c%10;
c/=10;
a[b]--;
cout<<b<<" ";
}
大数输出
数组思路
例如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进制:
#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 分)
随着卫星成像技术的应用,自然资源研究机构可以识别每一棵树的种类。请编写程序帮助研究人员统计每种树的数量,计算每种树占总数的百分比。
#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;
}
}