华为笔试

1.

我第一反应时写下了这样的程序:

#include <IOSTREAM>
using namespace std;
void main(){
    int x=100,y=50,z=20;
    int count=0;
    for(int i=0;i<=x;i++)        //循环次数: 100*50*20
    {
        for(int j=0;j<=y;j++)
        {
            for(int l=0;l<=z;l++)
                if(i+2*j+5*l==100)
                {
                    cout<<"组合中:1,2和5的个数分别是:"<<i<<"  "<<j<<"  " <<l<<endl;
                    count++;
                    break;
                }
        }
    }
    cout<<"总计的组合情况有:"<<count<<"种"<<endl;
}

但是,事实上这并不是人家想要的答案,其实,大部分的人都是这样,在问别人问题的时候,心理已经有了答案,那么其他人回答问题的时候,就会去比较,叫做期待值,很明显我写的这个程序,根本就不是人家想要的,其实这是一道明显的数学问题,而不是单纯的编程问题,从题目中可以看出:

1*x+2*y+5*z=100;  0<=x<=100;  0<=y<=50;  0<=z<=20;    所以:5z=100-x-2*y;  z的取值为21个,所以真正要做的循环只有21次而已,并且还要补充的知识有,

当z=0,那么也就是说x+2*y=100 可能的情况有在100内的偶数的个数决定,当z=1时,x+2*y=95可能的情况为95以内的奇数决定:

验证代码://奇数和偶数的判别, 在一个数的范围内
#include <iostream>
using namespace std;
void main(){
    int x;
    int oushu=0,jishu=0;
    cout<<"请输入您要的数:来计算0到这个数间的奇数和偶数个数:"<<endl;
    cin>>x;
    for(int i=0;i<=x;i++)
    {
        if(i%2==0) oushu++;
        else  jishu++;
    }
    cout<<"偶数个数为:"<<oushu<<endl;
    cout<<(x+2)/2<<endl;
    cout<<"奇数个数为:"<<jishu<<endl;
//    cout<<(x+2)/2<<endl;    //如果输入的是奇数,这个是正确的公式
    cout<<(x+1)/2<<endl;    //这个就没有限制了
    
}

改过之后的代码:

#include <IOSTREAM>
using namespace std;
void main(){
    int z=20;
    int count=0;
    for(int i=0;i<=z;i++)        //循环次数: 21次
    {
        count=count+((100-i*5)+2)/2;
    }
    cout<<"总计的组合情况有:"<<count<<"种"<<endl;
}

结果都是541次,证明改进这个是对的,在做了一些简单的数学分析,程序便高效了很多,再一次证明了 程序=数据结构 + 算法  但是,简单算法的程序,可以在调试阶段进行验证,良好的调试手段,比如:

#ifdef DEBUG
int simple();
#end if
int optimize();
......
in a function:
{
result=optimize();
ASSERT(result==simple());
}          这个看不大懂啊,

在工程设置里有一些设置会对该工程自动产生一系列的宏,用以控制程序的编译和运行。就好象楼上说的一样,如果你把代码夹在#ifdef DEBUG 和对应的 #endif 中间,那么这段代码只有在调试(DEBUG)下才会被编译。也就是说,如果你在RELEASE模式下,这些代码根本就不会存在于你的最终代码里头。

你可以手动实现DEBUG的定义如:

#define DEBUG

那么你的 #ifdef DEBUG 就会是真的。夹在中间的代码会进行编译,可以说,这些宏代码本身是面向编译器使用的,不要用来实现你的业务逻辑代码,这样会带来很不好的影响。这类宏定义的一个典型应用就是产生/屏蔽调试信息,看下面的例子

Code
1 #include <iostream>
2 using namespace std;
3
4 #ifdef DEBUG
5 inline void msg(){ cout<<"I'm testing"; }
6 #else
7 inline void msg() {}
8 #endif
9
10 int main()
11 {
12 msg();
13
14 return0;
15 }


上面的代码在DEBUG 模式下是会输出一句话的,你可以把这种应用放在你希望对程序的执行过程进行跟踪的代码里,为它们加上一些‘痕迹’,方便你进行判断。而在其他模式(RELEASE)下,这个函数只不过是一个空函数,又因为它是inline的,所以它实际上不会为你产生任何代码。这样你就能为自己的代码带来一种非常实用的效果,既能在DEBUG模式下为你提供判断的依据,又能在最终的RELEASE版中方便的抛弃掉它们,而不需要你手动地删除掉那些代码。
作为宏指令,如果定义了DEBUG宏那么编译#IF后面到#ENDIF的代码否则不编译DEBUG宏一般是编译器产生,如果编译模式是DEBUG就会产生这个宏,如果是RELEASE就不会

2.


/*
一个学生的信息是:姓名,学号,性别,年龄等信息,用一个链表,把这些学生信息连在一起,
给出一个age, 在些链表中删除学生年龄等于age的学生信息。
*/
#include <STDIO.H>
#include <STDLIB.H>
typedef struct Student
{
    char name[20];
    char num[11];
    char sex[8];
    int age;
    Student *next;
}*LinkList;
int n;
void CreateList(LinkList &L,int n)
{
    L=(LinkList)malloc(sizeof(Student));
    L->next=NULL;
    LinkList driect,Next;
    driect=L;
    printf("请输入你的姓名:\n");
    scanf("%s",driect->name);
    printf("请输入你的学号:\n");
    scanf("%s",driect->num);
    printf("请输入你的性别:\n");
    scanf("%s",driect->sex);
    printf("请输入你的年龄:\n");
    scanf("%d",&driect->age);     //bug there,输入格式
    for(int i=0;i<n-1;i++)
    {
        Next=(LinkList)malloc(sizeof(Student));
        driect->next=Next;
        printf("请输入你的姓名:\n");
        scanf("%s",Next->name);
        printf("请输入你的学号:\n");
        scanf("%s",Next->num);
        printf("请输入你的性别:\n");
        scanf("%s",Next->sex);
        printf("请输入你的年龄:\n");
        scanf("%d",&Next->age);     //bug there,输入格式
        Next->next=NULL;
        driect=Next;
        
    }
    printf("学生链表创建成功!\n");
    
}
void ShowList(LinkList &L,int n)
{
    LinkList driect;
    driect=L;
    for(int i=0;i<n;i++)
    {
        printf("学号为%s你的姓名%s:\n",driect->num,driect->name);
//        printf("学号为%s你的学号%s:\n",driect->num);
        printf("学号为%s你的性别%s:\n",driect->num,driect->sex);
        printf("学号为%s你的年龄%d:",driect->num,driect->age);
        driect=driect->next;
        printf("\n");
    }
    printf("学生链表显示成功!\n");
}
void DeleteAge(LinkList &L,int aged)
{
    LinkList driect,Next;
//    LinkList driect;
    driect=L;
//    printf("%d,%d",L->age,aged);
    while((driect->age)!=aged)     //bug there
    {
//        printf("%d,%d",L->age,aged);   哦我知道了,这个循环没有结束
        Next=driect;

        driect=driect->next;
        if(driect==NULL)
        {
            printf("学生链表中,不存在该年龄的学生信息\n");
            return ;
        }
    }
        printf("what");


        Next->next=driect->next;
//        free(driect);
        printf("学生信息,删除成功!\n");
        n--;
    
    
}
void main(){
    printf("请输入所要输入学生的个数:\n");
    
    scanf("%d",&n);
    LinkList L;
    CreateList(L,n);
    ShowList(L,n);
    printf("请输入所要删除学生年龄的学生信息\n");
    int aged;
    scanf("%d",&aged);
//    printf("what");
    DeleteAge(L,aged);
//    printf("what");
    ShowList(L,n);

}

3.

#include <IOSTREAM>
#include <STRING>
using namespace std;
void BigCSmell(char *ch,int lenth)
{    
    for(int i=0;i<lenth-1;i++)
    {
        if(ch[i]<=122 && ch[i]>=97)
        {
//            char x;
//            x=ch[i];
            ch[i]=ch[i]-32;
//            ch++;
        }
    }
}
void main(){
    char ch[20];
    printf("请输入字符串。。。。\n");
    scanf("%s",ch);
    int lenth=strlen(ch);
    BigCSmell(ch,lenth);   //注意:函数调用数组的时候的格式
    printf("改变后的字符串为:%s\n",ch);
}

4.随机输入一个数,判断它是不是对称数(回文数)(如3,121,12321,45254)。不能用字符串库函数   

//回文的概念 字符串的对称 比如:level
#include <STDIO.H>
#include <STRING>
int fun(char *p)
{
    int lenth;
    lenth=strlen(p);
    if(lenth%2==0)
    {
        while(lenth/2>0)
        {
            if(*p!=*(p+lenth-1))  return 0;
            else  {
                lenth-=2;
                p++;
            }
        }
        return 1;
    }
    else
    {
        while(lenth/2>1)
        {
            if(*p!=*(p+lenth-1))  return 0;
            else  {
                lenth-=2;
                p++;
            }
        }
        return 1;
    }
}
void main(){
    char *q="abba";
//    printf("please input your char* \n");
//    scanf("%s",q);
//    printf("%s",q);
    int x;
    x=fun(q);
    switch(x)
    {
    case 1:
        printf("yes\n");break;
    case -1:
        printf("wrong\n");break;
    case 0:
        printf("no\n");break;
        
    }
}
//好啦,真是的中算是结果对了,可是为-1的情况,没有考虑到,看看答案咋写的吧
int fun(char *p)
{
    int len=strlen(p)-1;
    char *q=p+len;    //直接可以将另一个指针指向字符串的末尾
    if(!p)  return -1;  //这就是错误?   我去
    while(p<q)
    {
        if((*p++)!=(*q--)) return 0;
    
    }
    return 1;
}

5.求2~2000的所有素数.有足够的内存,要求尽量快

我的代码://求2~2000的所有素数.有足够的内存,要求尽量快
//素数:质数,又称素数,指在一个大于1的自然数中,除了1和此整数自身外,无法被其他自然数整除的数
#include <stdio.h>
#include <MATH.H>
void Sushu()
{
    int half;
    int cout=0;
    int i=2;
    while(i<=2000)
    {
        int j=2;
        half=sqrt(i);
        if(j>half)
        {
            printf("this is sushu :%d   ",i);
            cout++;
        }
        else
        {
            for(j=2;j<=half;j++)
            {
                
                if(i%j==0)
                {
                    
                    break;
                }
                if(j==half)
                {
                    cout++;
                    printf("this is sushu :%d   ",i);
                    if(cout%4==0) printf("\n");
                }
            }
        }
        i++;    
    }
}
void main(){
    printf("请输出2~2000的素数:\n");
    Sushu();
    printf("\n");
}

答案的代码:

int findvalue[2000]={2};
static int find=1;
bool adjust(int value)
{
assert(value>=2);
if(value==2) return true;
for(int i=0;i<=find;i++)
{
if(value%findvalue[i]==0)
return false;
}
findvalue[find++];
return true;
}    //给的代码,看不大懂啊


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值