您的位置:首页 > 其它

2014华为机试真题(1)

2015-08-10 22:57 260 查看

1.及格线问题

10个学生考完期末考试评卷完成后,A老师需要划出及格线,要求如下:

(1) 及格线是10的倍数;

(2) 保证至少有60%的学生及格;

(3) 如果所有的学生都高于60分,则及格线为60分

#include<iostream>
using namespace std;

/**********************solution1************************************/
int cmp(const void *a,const void *b)
{
return *(int*)a-*(int*)b;
}
template<unsigned int N,typename T>
int process1(T (&data)
){
qsort(data,N,sizeof(T),cmp);
if(data[0]>=60)
return 60;
else
return data[4]/10*10;
}

/**********************solution2************************************/
template<unsigned int N,typename T>
int process2(T(&data)
){
int* count=new int[11];
memset(count,0,11*sizeof(int));

for(int i=0;i<N;i++)
count[data[i]/10]++;

if(count[10]==10)
return 10;
else if(count[10]>=6)
return 100;

for(int i=9;i>=0;i--){
count[i]+=count[i+1];
if(i>=6&&count[i]==10)
return 60;
else if(count[i]>=6)
return i*10;
}

delete []count;
}

int main(int argc, char *argv[])
{
int a[]={100,100,100,100,100,43,30,20,41,42};
printf("%d\n",process2(a));
}


solution1使用了快速排序库函数。其中包含自定义比较函数cmp。对于浮点型,一定要使用三目运算符。其中的qsort函数包含在<stdlib.h>的头文件里,strcmp包含在<string.h>的头文件里。这里总结如下,对于从小到大排序:

int num[100];
int cmp ( const void *a , const void *b )//int
{
return *(int *)a - *(int *)b;
}
qsort(num,100,sizeof(num[0]),cmp);

char word[100];
int cmp( const void *a , const void *b )//char
{
return *(char *)a - *(int *)b;
}
qsort(word,100,sizeof(word[0]),cmp);

double in[100];
int cmp( const void *a , const void *b )//double
{
return *(double *)a > *(double *)b ? 1 : -1;
}
qsort(in,100,sizeof(in[0]),cmp);

struct In
{
double data;
int other;
}s[100]
int cmp( const void *a ,const void *b)//结构体一级
{
return ((In *)a)->data > ((In *)b)->data ? 1 : -1;
}
qsort(s,100,sizeof(s[0]),cmp);

struct In
{
int x;
int y;
}s[100];
int cmp( const void *a , const void *b )//结构体二级
{
In *c = (In *)a;
In *d = (In *)b;
if(c->x != d->x) return c->x - d->x;
else return d->y - c->y;
}
qsort(s,100,sizeof(s[0]),cmp);

struct In
{
int data;
char str[100];
}s[100];
int cmp ( const void *a , const void *b )//结构体按字符串排序
{
return strcmp( ((In *)a)->str , ((In *)b)->str );
}

qsort(s,100,sizeof(s[0]),cmp);


2.亮灯的数目

一条长廊里依次装有n(1≤n≤65535)盏电灯,从头到尾编号1、2、3、…n-1、n。每盏电灯由一个拉线开关控制。开始,电灯全部关着。

有n个学生从长廊穿过。第一个学生把号码凡是1的倍数的电灯的开关拉一下;接着第二个学生把号码凡是2的倍数的电灯的开关拉一下;接着第三个学生把号码凡是3的倍数的电灯的开关拉一下;如此继续下去,最后第n个学生把号码凡是n的倍数的电灯的开关拉一下。n个学生按此规定走完后,长廊里电灯有几盏亮着。

注:电灯数和学生数一致。不能写笨拙的双重循环(优化过的是可以的),会运行超时。本题有运行时间限制(一说10000ms)。

输入 65535 输出 255

基本思路:

对于任何一盏灯,由于它原来不亮,那么当它的开关被按奇数次时,灯是开着的;当它的开关被按偶数次时,灯是关着的;一盏灯的开关被按的次数,恰等于这盏灯的编号的因数的个数;要求哪些灯还亮着,就是问哪些灯的编号的因数有奇数个.显然完全平方数有奇数个因数。每个数除以一个数A等于另一个数B,那么A和B都是它的因数,于是因数是成对出现的,但是要因数是奇数,就必须A=B所以这个数就必须是一个是的平方得到的。

综上所述这道题非常简单,就是找1-65535中完全平方数的个数。

int main(int argc, char *argv[])
{
int n;
while(~scanf("%d",&n)){
int ans=0;
for(int i=1;;++i)
{
if(i*i>n)
break;
++ans;
}
printf("%d\n",ans);
}
return 0;
}



3.计算最大值最小值之外的个数

int count(){
int temp;
cin>>temp;
int max=temp,min=temp;
int i=1,j=1,k=1;
char c;
cin>>c;
while(c!='\n'){
cin>>temp;
k++;
if(temp<min){
min=temp;
i=1;
}
else if(temp==min)
i++;
else if(temp==max)
j++;
else if(temp>max){
max=temp;
j=1;
}
scanf("%c",&c);//c=getchar()
}
if(k==1||min==max)
return 0;
else
return k-i-j;
}
scanf和getchar函数都可以读取空白符。


4.括号的匹配问题

输入一串字符串,其中有普通的字符与括号组成(包括‘(’、‘)’、‘[’,']'),要求验证括号是否匹配,如果匹配则输出0、否则输出1.

Smpleinput:dfa(sdf)df[dfds(dfd)] Smple outPut:0

int match(){
stack<char> s;
char p;
scanf("%c",&p);
while(p!='\n'){
if(p=='('||p=='[')
s.push(p);
else if(p==')'){
if(!s.empty()&&s.top()=='(')
s.pop();
else
return 1;
}
else if(p==']'){
if(!s.empty()&&s.top()=='[')
s.pop();
else
return 1;
}
scanf("%c",&p);
}
if(s.empty())
return 0;
else
return 1;
}



5.判断是否为回文数

int decision(){
int n,m=0;
cin>>n;
int temp=n;
while(temp){
m*=10;
m+=(temp%10);
temp/=10;
}
if(m==n)
return 1;
else
return 0;

}
本质上,即计算该数的逆序数,比较该逆序数是否和原来的数相等


6.翻译英文数字

例如:

输入:OneTwoThree

输出:123

输入:OneTwoDoubleTwo

输出:1222

输入:1Two2

输出:ERROR

输入:DoubleDoubleTwo

输出:ERROR

有空格,非法字符,两个Double相连,Double位于最后一个单词 都错误。

const string process(const string& s){
const char* num[]={"zero","one","two","three","four","five","six","seven","eight","nine"};
if(s.empty())
return "error";
int i=0;
bool flagDouble=false;
bool flagNumber;
string result;
while(i<s.length()){
flagNumber=false;
if(isalpha(s[i])){//先判断是否是字母

for(int j=0;j<10;j++){//判断数字
if((i+strlen(num[j])-1)<s.length()&&!strcmp(s.substr(i,strlen(num[j])).c_str(),num[j])){
result+=(char)(j+'0');
i+=strlen(num[j]);
if(flagDouble){//该数字是否需要重复
result+=(char)(j+'0');
flagDouble=false;
}
flagNumber=true;//数字判断成功
break;
}
}

if(!flagNumber&&(i+5)<s.length()&&!strcmp(s.substr(i,6).c_str(),"double")){//判断double
if(!flagDouble){
flagDouble=true;
i+=6;
}
else//double之前已经出现过
return "error";
}

if(!flagNumber&&!flagDouble)//double和数字都未判读成功
return "error";
}
else
return "error";//非字母
}

if(flagDouble)//防止,double与数字没有匹配,即单个double出现
return "error";
else
return result;
}
int main(int argc, char *argv[])
{
string s;
getline(cin,s);
cout<<process(s)<<endl;
}


7.不重复逆序输出整数

输入一个整数,如12336544,或1750,然后从最后一位开始倒过来输出,最后如果是0,则不输出,输出的数字是不带重复数字的,所以上面的输出是456321和571。如果是负数,比如输入-175,输出-571。

int reverseNum(int num){
int* flag=new int[10];
int result=0;
int plus=true;
memset(flag,0,10*sizeof(int));

if(num<0){
num=abs(num);
plus=false;
}

while(!(num%10))
num/=10;

int temp;
while(num){
temp=num%10;
if(!flag[temp]){
result*=10;
result+=temp;
flag[temp]+=1;
}
num/=10;
}
if(!plus)
return -1*result;
else
return result;
}
int main(int argc, char *argv[])
{
cout<<reverseNum(-12336544)<<endl;
}


8.模拟减法运算

输入两行字符串正整数,第一行是被减数,第二行是减数,输出第一行减去第二行的结果。

备注:1、两个整数都是正整数,被减数大于减数

示例:

输入:1000000000000001

1

输出:1000000000000000

注意大数用char a[]存储,用%s接收,一位一位的运算。注意a[0]里的正负号

const char* sub(const string& num1,const string& num2){

if(num1.empty()||num2.empty())
return NULL;
int temp;
int add=0;
int size1=num1.length();
int size2=num2.length();
char* result=new char[size1+1];
memset(result,'\0',size1+1);

int i;
for(i=0;i<size2;i++){
temp=num1[size1-i-1]-num2[size2-i-1]-add;
add=0;
if(temp<0){
temp+=10;
add=1;
}
result[size1-i-1]=temp+'0';
}
if(size1>size2)
result[size1-i-1]=num1[size1-i-1]-add;

for(i=0;i<(size1-size2-1);i++)
result[i]=num1[i];

//删除空白部分
i=0;
while(result[i]=='0')//开头存在0的情况
i++;
strcpy(result,result+i);
return result;
}

int main(int argc, char *argv[])
{
string num1,num2;
getline(cin,num1);
getline(cin,num2);
cout<<sub(num1,num2)<<endl;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: