2014华为机试真题(1)

来源:互联网 发布:匡恩网络 b轮 融资 编辑:程序博客网 时间:2024/04/29 23:48

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)[N]){ 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)[N]){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();elsereturn 1;}else if(p==']'){if(!s.empty()&&s.top()=='[')s.pop();elsereturn 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;elsereturn 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")){//判断doubleif(!flagDouble){flagDouble=true;i+=6;}else//double之前已经出现过return "error";}if(!flagNumber&&!flagDouble)//double和数字都未判读成功return "error";}elsereturn "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;elsereturn 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;}









0 0