NewCoder-- 华为OJ题目详解(一)
来源:互联网 发布:php url 特殊字符转义 编辑:程序博客网 时间:2024/05/06 04:12
今天也算是第一天写CSDN博客,想跟你们一起讨论和解析一下牛客网华为OJ的题目,同时也能增进自己的算法能力。事不宜迟,我们开始吧!
1.字符串最后一个单词的长度
题目描述
计算字符串最后一个单词的长度,单词以空格隔开。
输入描述:
一行字符串,非空,长度小于5000。
输出描述:
整数N,最后一个单词的长度。
输入例子:
hello world
输出例子:
5
这是一道非常简单的题目,直接给代码吧–>–>
#include<iostream>#include<cstring>using namespace std;#define max 100000int main(){ int number=0,i,len; char s[max]; gets(s); len=strlen(s); for(i=len-1;i>=0;i--) { if(s[i]==' ') { number=len-1-i;break; #直观法,遇到空格则break } } if(number!=0)cout<<number<<endl; else cout<<len<<endl; return 0;}
2.计算字符个数
题目描述
写出一个程序,接受一个有字母和数字以及空格组成的字符串,和一个字符,然后输出输入字符串中含有该字符的个数。不区分大小写。
输入描述:
输入一个有字母和数字以及空格组成的字符串,和一个字符。
输出描述:
输出输入字符串中含有该字符的个数。
输入例子:
ABCDEF
A
输出例子:
1
这道题也是一道非常简单的入门题,直接用数组可以实现,直接现代码吧–>
#include<iostream>#include<cstring>using namespace std;#define max 100000int main(){ char ch,s[max];int f=1,t[max]; #设置标志位 gets(s);memset(t,0,sizeof(t)); for(int i=0;i<strlen(s);i++) {t[s[i]]++;} #枚举每一位 cin>>ch; for(int i=0;i<strlen(s);i++) { if(ch==s[i]) {f=0; cout<<t[s[i]]<<endl;break; } } if(f==1)cout<<"0\n"; #标志位,大于串长度输出"0" return 0;}
3.明明的随机数
明明想在学校中请一些同学一起做一项问卷调查,为了实验的客观性,他先用计算机生成了N个1到1000之间的随机整数(N≤1000),对于其中重复的数字,只保留一个,把其余相同的数去掉,不同的数对应着不同的学生的学号。然后再把这些数从小到大排序,按照排好的顺序去找同学做调查。请你协助明明完成“去重”与“排序”的工作。
Input Param
n 输入随机数的个数
inputArray n个随机整数组成的数组
Return Value
OutputArray 输出处理后的随机整数
注:测试用例保证输入参数的正确性,答题者无需验证。测试用例不止一组。
输入描述:
输入多行,先输入随机整数的个数,再输入相应个数的整数
输出描述:
返回多行,处理后的结果
输入例子:
11 10 20 40 32 67 40 20 89 300 400 15
输出例子:
10 15 20 32 40 67 89 300 400
这是一道数字去重和排序的问题.我的方法当然不是最好的,却是最直观的.先定义一个结果数组,初始化a[0]进行比较;然后依次输入其他值b进行直接插入排序,
最后输出。可是时间复杂度相对较高.
#include<iostream>#include<cstring>using namespace std;int main(){ int n,a[1000],b; #定义a数组储存结果 while(cin>>n) { cin>>a[0];int aLen=1;n--; #先输入第一个数进行比较 while(n--) { cin>>b; #每次输入一位随机数进行比较 int i=0; for(i=0;i<aLen;i++) #遍历a数组 if(b==a[i]||b<a[i])break; #使用直接插入法间接实现排序 if(b<a[i]) #小于的话,将b插入到a数组适合的位置(直接插入法) { for(int j=aLen-1;j>=i;j--)a[j+1]=a[j]; a[i]=b; aLen++; } else if(b>a[i]) #大于的话,将b直接插入到a数组尾部,长度+1 { a[aLen]=b;aLen++; } } for(int j=0;j<aLen;j++)cout<<a[j]<<endl; } return 0;}
下面有个时间复杂度更优的解法,适合小数据:
#include <iostream>using namespace std;int main() { int N, n; while (cin >> N) { int a[1001] = { 0 }; #每次使用前数组清零 //memset(a,0,sizeof(a)); while (N--) { cin >> n; a[n] = 1; #每次输入一位标记一位,重复数字恒置 } for (int i = 0; i < 1001; i++) if (a[i]) #非零即输出 cout << i << endl; } return 0;}
后面的解法虽然简单直观,但是不提倡—>—>
4.字符串分隔
题目描述
•连续输入字符串,请按长度为8拆分每个字符串后输出到新的字符串数组;
•长度不是8整数倍的字符串请在后面补数字0,空字符串不处理。
输入描述:
连续输入字符串(输入2次,每个字符串长度小于100)
输出描述:
输出到长度为8的新字符串数组
输入例子:
abc
123456789
输出例子:
abc00000
12345678
90000000
这道题我定义了两个数组,一个源数组存储原来的数字,另一个储存输出的数字
实现数组间转移:够数则复制,不够则补0.
#include<iostream>#include<cstring>using namespace std;char *copy(char *dst,char *src,int n) #这里我定义了两个数组指针,分别指向目标(输出)数组和源数组{ for(int i=0;i<n;++i){ if(src[i]) dst[i]=src[i]; #原数组里的值非零即转移保存 else dst[i]='0'; #为零的话补零 } return dst; #返回结果数组指针}int main(){ char buf[112]={0}; char out[9]={0}; while(gets(buf)){ char *p=buf; while(*p){ cout<<copy(out,p,8)<<endl; p+=8; } memset(buf,0,sizeof(buf)); #每次使用完清空数组 }}
5.进制转换
题目描述
写出一个程序,接受一个十六进制的数值字符串,输出该数值的十进制字符串。(多组同时输入 )
输入描述:
输入一个十六进制的数值字符串。
输出描述:
输出该数值的十进制字符串。
输入例子:
0xA
输出例子:
10
不解释上代码
#这种方法就是牛,打开世界的大门include <iostream>using namespace std;int main(){ int x; while(cin>>hex>>x) cout<<x<<endl; return 0;}
当然进制转换还有很多的方法,我这里只是用了小技巧AC题目罢了
6.质数因子
输入一个正整数,按照从小到大的顺序输出它的所有质数的因子(如180的质数因子为2 2 3 3 5 )
最后一个数后面也要有空格
详细描述:
函数接口说明:
public String getResult(long ulDataInput)
输入参数:
long ulDataInput:输入的正整数
返回值:
String
输入描述:
输入一个long型整数
输出描述:
按照从小到大的顺序输出它的所有质数的因子,以空格隔开。最后一个数后面也要有空格。
输入例子:
180
输出例子:
2 2 3 3 5
原理都是从最小的质数因子”2”下手,一步步增1,直到所有的质数因子全部输出
笔者曾经使用过python代码去AC
import syswhile True: try: number = long(sys.stdin.readline()) i = 2 while number != 1: while number % i == 0: #一直取余一直输出 print i, number = number / i i = i + 1 #当前质数因子加1 print "", except: break
python代码是不是很简单?C++也挺简单的
#include<iostream>using namespace std;void change(int n){ int x=2; while(x*x<=n){ #从2开始,每次进行平方 while(n%x==0){ #同理,一直取余一直输出 cout<<x<<" "; n=n/x; } x++; #当前质数因子加1 } if(n>1) cout<<n<<' '; #输出格式控制}int main() { int n; cin>>n; change(n); return 0;}
7.取近似值
题目描述
写出一个程序,接受一个正浮点数值,输出该数值的近似整数值。如果小数点后数值大于等于5,向上取整;小于5,则向下取整。
输入描述:
输入一个正浮点数值
输出描述:
输出该数值的近似整数值
输入例子:
5.5
输出例子:
6
这是道精度四舍五入处理的问题,笔者这里用到了C++ STL里的库函数
—-> static_cast < type-id > ( expression )
该运算符把expression转换为type-id类型,但没有运行时类型检查来保证转换的安全性。它主要有如下几种用法:
①用于类层次结构中基类(父类)和派生类(子类)之间指针或引用的转换。
进行上行转换(把派生类的指针或引用转换成基类表示)是安全的;
进行下行转换(把基类指针或引用转换成派生类表示)时,由于没有动态类型检查,所以是不安全的。
②用于基本数据类型之间的转换,如把int转换成char,把int转换成enum。这种转换的安全性也要开发人员来保证。
③把空指针转换成目标类型的空指针。
④把任何类型的表达式转换成void类型。
百科地址:(可自行查阅)
static_cast
#include<iostream>using namespace std;int main(){ float x; while(cin>>x){ if(x-static_cast<int>(x)>=0.5) cout<<static_cast<int>(x)+1<<endl; # 用法:static_cast < type-id > ( expression) else cout<<static_cast<int>(x)<<endl; } return 0;}#该函数能够很好的保留精度
8.合并表记录
题目描述
数据表记录包含表索引和数值,请对表索引相同的记录进行合并,即将相同索引的数值进行求和运算,输出按照key值升序进行输出。
输入描述:
先输入键值对的个数
然后输入成对的index和value值,以空格隔开
输出描述:
输出合并后的键值对(多行)
输入例子:
4
0 1
0 2
1 2
3 4
输出例子:
0 3
1 2
3 4
因为要处理“键值对”问题,所以笔者这里用到了c++中的一个容器map
Map是c++的一个标准容器,提供了很好一对一的关系(键值对),在一些程序中建立一个map可以起到事半功倍的效果,它会自动建立Key - value的对应。key 和 value可以是任意你需要的类型。
总结了一些map基本简单实用的操作!
#map的基本操作函数: begin() 返回指向map头部的迭代器 clear() 删除所有元素 count() 返回指定元素出现的次数 empty() 如果map为空则返回true end() 返回指向map末尾的迭代器 equal_range() 返回特殊条目的迭代器对 erase() 删除一个元素 find() 查找一个元素 get_allocator() 返回map的配置器 insert() 插入元素 key_comp() 返回比较元素key的函数 lower_bound() 返回键值>=给定元素的第一个位置 max_size() 返回可以容纳的最大元素个数 rbegin() 返回一个指向map尾部的逆向迭代器 rend() 返回一个指向map头部的逆向迭代器 size() 返回map中元素的个数 swap() 交换两个map upper_bound() 返回键值>给定元素的第一个位置 value_comp() 返回比较元素value的函数
百度(可以自行查阅):键值对
不说这么多,直接上代码
#include<iostream>#include<map>using namespace std;int main(){ int n;while(cin>>n){ map<int,int>m; #map容器 while(n--){ int key,value; cin>>key>>value; if(!m[key])m[key]=value; #不同则建立 else m[key]+=value; #相同则累加 } for(map<int,int>::iterator it=m.begin();it!=m.end();++it){ #使用迭代器输出键值对 cout<<it->first<<" "<<it->second<<endl; } } return 0;}
看吧。代码是不是相当简单呢
9.提取不重复的整数
题目描述
输入一个int型整数,按照从右向左的阅读顺序,返回一个不含重复数字的新的整数。
输入描述:
输入一个int型整数
输出描述:
按照从右向左的阅读顺序,返回一个不含重复数字的新的整数
输入例子:
9876673
输出例子:
37689
从右向左的阅读顺序读取数字去重,因为是数字,所以这里会涉及到一些数字处理的代码 num=num*10+n%10; #乘以位权再加上每步余数
#include<iostream>using namespace std;int main(){int n;int a[10]={0};int num=0;cin>>n;while(n){ if(a[n%10]==0) { #取余表示从最右边读起 a[n%10]++; num=num*10+n%10; #乘以位权再加上每步余数 } n/=10; } cout<<num<<endl; return 0;}
10.字符个数统计
题目描述
编写一个函数,计算字符串中含有的不同字符的个数。字符在ACSII码范围内(0~127)。不在范围内的不作统计。
输入描述:
输入N个字符,字符在ACSII码范围内。
输出描述:
输出范围在(0~127)字符的个数。
输入例子:
abc
输出例子:
3
这道题太直观了,怎么做都行
#include<iostream>using namespace std;int main(){ char ch; int a[128]={0}; int cnt=0; while(cin>>ch){ if(ch>=0&&ch<=127)a[ch]++; } for(int i=0;i<128;i++) if(a[i]>0)cnt++; cout<<cnt<<endl;}
#include<iostream>#include<string>using namespace std;int main(){ string x; getline(cin,x); int cnt=0; for(int i=0;i<=127;++i) if(x.find(i)!=string::npos) cnt++; cout<<cnt<<endl; return 0;}
#include<iostream>#include<set>using namespace std;int main(){ char ch; set<char>s; while(cin>>ch) { if(ch>=0&&ch<=127) s.insert(ch); } cout<<s.size()<<endl; return 0;}
好了,今天就介绍十题给大家,不知不觉学了很多,欢迎大家讨论。
- NewCoder-- 华为OJ题目详解(一)
- 华为OJ一个题目
- newcoder 题目: Xorto
- 华为OJ题目 配置文件恢复
- 华为OJ(一)
- 华为OJ训练一
- oj平台题目一
- 华为OJ题目(一):找出字符串中第一个出现一次的字符
- 华为oj题目 DNA序列 [java语言]
- 华为OJ题目 句子逆序 java
- 华为OJ题目:24点运算
- 华为OJ平台题目:火车进站
- 华为OJ平台题目:蛇形矩阵
- 华为OJ题目(三):字符统计
- 华为OJ题目(四):字符逆序
- 华为OJ题目(七):字符串加密
- 华为OJ题目(九):百钱买百鸡问题
- 华为OJ题目(十):称砝码
- 指针变量
- matconvnet分步注释(四)网络设置
- Ubuntu使用技巧
- android Binder详解
- redis故障转移sentinel
- NewCoder-- 华为OJ题目详解(一)
- JS中的return falase及return使用方式
- Climping Stairs lintcode/leetcode
- 使用双指针参数传递
- Link-based and Probe-based public network
- 高通LCD之显示帧数据简析
- ubuntu上网慢的解决办法
- 奇异值分解及几何意义
- BeanUtils组件 学习笔记