打印

小菜菜准备学C

公元5月31日
好几天都没学习了,单位事情太多,再加上自己的懒惰,我真得很懒惰,怎么办呢,自己不能督促自己,尤其是在这样一个物欲横流的社会,发店感慨把,怪自己订立不够,真是的,不说了,今天有个问题问大家,就是关于互换两个变量的函数,这是我写的:

   main()
  {
    int swap(int x,int y);
    int a=2,b=3;
    printf("%d%d",swap(a,b));
   }
   int swap(int x,int y)
  {
    int t;
   t=x;x=y;y=t;
   return(x,y);
   }
  结果却不是很乐观亚,输出的值不对,后来我又琢磨了,是不是函数的返回直只能返回一个数值呀,也就是return的返回直只能是一个呀,那交换函数怎么做呀?return(x,y)这种写法到底对不对呢?那交换两个变量的直的函数又怎么写呢?

打印99表

表1 :

  main()
{
  int i,j;
  for(i=1;i<=9;i++)
   {
    for(j=1;j<=9;j++)
    {
      print("%d ",i*j);
     }
     printf("/n");
     }
}
表2;

  for(i=1;i<=9;i++)
   for(j=1;j<=i;j++)
    {
      printf("%d*%d=%d",j,i,i*j);
     }
   printf("/n");

TOP

输入3个数,找出其中最大的,或者找出最小的,象这样的题最近看的很多,现在我想写出一个通式来,输入N个数找出其中最大的或者最小的,
   main()
  {
    int max,min,i,m,n;
    scanf("%d",&n)
    先告诉计算机,你要输入多少个数,循环的时候用。
    scanf("%d",&m);
   先接收一个数,然后副职给max,min
     max=min=m;
     for(i=1;i<n;i++)
   {
     scanf("%d",&m);
      if(m>max)
      max=m;
      if(m<min)
      min=m;
    }
   printf("%d%d",max,min);
}
当然我们也可以用^z来结束输入。
  # include stdio.h
   main()
  {
    int max,min,m;
    scanf("%d",&m);
    max=min=m;
    while(scanf("%d",&m)!=eof)
     {
         if(m>max)
           max=m;
         if(m<min)
          min=m;
       }
   printf("%d%d",max,min);
}
      这个还没有调试,如果不对请大家指正.

TOP

找出最小值的一个应用就是排序,假设有一组数,就是假设有N 个数,找出最小的,然后放在第一个位置,然后在从N-1个数中找出最小的放在第二个位置,这样的算法就是给数列排序,由小到大的排序,程序如下:
  这道题很玄妙呀
  main()
  {
    int a[10]={1,2,3,4,5,6,7,8,9,10};
    首先定义一个数组,并且赋初值。
    然后定义所需要变量,i,j是循环用的,因为是双重循环, k是为了替换最小值的下标用的,t是为了交换最小值和最前位置的。
    int i,j,k,t;
    for(j=0;j<=8;j++)
       循环到8,也就是n个数,从第一个数开始比,比n-1次就行了,所以10 个数,比9次就可以了
     {
        k=j;
        for(i=j+1;i<=9;i++)
         if(a<a[k])
            k=i;
每次是怎么比的,从第一个数,给他提出来,也就是a[0],然后,分别用他后边的数,j+1到9,来和他比,如果比他小,就把下标替换出来,存到K里边,然后互相换
        t=a[j];a[j]=a[k];a[k]=t;
      }
  最后输出
    for(i=0;i<=9;i++)
      printf("%d ",a);
   }

TOP

昨天晚上玩了一会97,也没学习,因为是周末,就放松了对自己的要求,最近一段时间学习的很快,但是我个人感觉很浮噪,今天想作一些习题,巩固一下,数组这个概念是c语言的重要概念,塔为每个数提供了可以访问的下标,找到下标,就可以访问这个数了,就相当于学生的名字和学号,有了学号,就可以把学生组织起来,而且我现在感觉数组的下标更有利于方便简单明了的应用于循环中,因为下标都是挨着的一列数,虽然数组的数不挨着,但是下标都是从0开始的,依次排列,我们看下一道题目, 从键盘获取一组数,然后倒叙输出,如果不用数组,就很麻烦了,用数组,题目作起来相对简单一下。
   main()
  {
   int a[10],i;
   for(i=0;i<=9;i++)
    scanf("%d",&a);
   for(i=9;i>=0;i--)
    printf("%d ",a);
   }
  两个循环,第一个给数组赋值,下标从0开始,倒叙输出,循环就从最高的下标开始,一次输出。
  这道题目事先给出了数组的长度,如果是随机输入,就是你不知道用户要输入多少个数,用户想输入多少哥数都行,不局限再a[10]上,怎么办哪?
  我尝试写一下。
  #include "stido.h"
  main()
  {
   int a[100],i,j;
   i=0;
   while(scanf("%d",&a)!=EOF)
     i++;
   for(j=i-1;j>=0;j++)
    printf("%d",a[j]);
  }
  这个程序我认为写的很合理呀,给出数组的长度是100,够长了,然后让用户输入,从下标0开始赋值,用i作为累加器,然后当用户输入 ctrl+z的时候结束,然后再倒叙输出,但是调试的时候却出一大堆乱马,根本,就不对,到底怎么作哪,请高手指点亚!!

TOP

彻底解决了穿越沙漠问题:
穿越沙漠问题,呵呵,终于弄明白了,原题我就不复述了,这倒题要使用逆推法.就是求最优化,最省油的办法,
从前边开始推倒你会觉得无从下手,束手无策,呵呵,这道题憋屈我一个礼拜了,
  逆推法,就是从汽车最后一次开出沙漠起推倒,因为它是要求最节省油的方法,所以,我们,可以知道,最后一次开出沙漠,前加的油必然是500L,然后开出沙漠,没有浪费一滴油,就是,到最后一个加油站,加满500L,然后开出沙漠,所以,最后一个加油站储藏的必然是500L的油,
我们用一个变量K来存储加油站的个数,既然是倒推,也就是k=1的时候,加油站里边有500L油,然后逆推到第二个加油站,可以这样想,要想满足第一个加油站有500L油,那么第二个加油站需要放多少呢?有一点我们肯定知道,就是肯定是比500大的,如果距离很长,往后边还要排好多加油站的话,最多比500多500L,也就是1000L是做多的了,需要输入油多少次呢, 因为距离过程中需要消耗油,所以去一次肯定不能直接存500L,肯定这个数值是小于500,所以至少需要两次,第一次是往反的,第二次在送去就够了,旧不用再回去了,就是3次
  所以 向第一个加油站运送500L油的任务需要3次来完成,如果后边还有很多个加油站的话,我想,最大化,第二个加油站就是存1000L,最大化是个问题,后边我们再说,最大化,就是一个汽车最多带500升,

    那么它需要平均分出3份,去一份,放那一份,回来一份,也就是去是500/3,放那500/3,回来500/3,再去,500/3,放那500/2,凑够500,加满油,就开出去了。
    所以倒数第二个油战需要放1000升油,也就是分三次送完,路程就是500/3,耗油量就是1000升,接下来,再来推导要想保持倒数第二个油战有1000升,首先估算一下需要的送几次,肯定每次送到的油都小于500,因为还有路程可走,还得耗油,不可能直接飞过去呀,所以呀,呵呵,两次不到1000,只能是3次,单向3次,你想还得回来取两次油呀,所以就是5次,最后一次就直接往前开了,估算出了5次,是吧?下面我们就可以这样想了,我们要送前一个加油站1000升油,途中用油最少是500升,那么它走过的路程就是500/5,第三个加油站就得准备1500升,如此,战的数量和汽车往返的次数就形成了一个数量关系,就是2*k-1,,当然公里数就是  500/2*k-1,知道了这个程序就不难写了,

    大家都知道了吗? 为了便于理解,我再换一种思维,也为了自己掌握的巩固和提高,

     就是怎么的呢。

    问题1, 如果这段沙漠就500公里长,好,就在起始点加满500生,一路彪过去,欧了,呵呵,

    问题2,如果这段沙漠是600公里,也就是比500公里大,怎么办,还是按照刚才上边的方法,逆推法,当然,逆推不了几步,就是为了简单明了才选择600公里的,呵呵,逆推法,再500公里处,建设一个500升容量的加油站,那么要再起始点放多少油呢,按照上边的推导,肯定要放3次,600-500,这个很有用的啊,就是看还剩多少公里,算出来了,是100公里,往返3次,就是300公里,也就是300升油的消耗,路上消耗300升,再加上要运送到第一个加油站的500生,就是800升,所以答案就是800升,
   
   问题3,也就是我们再考虑,如果不是600哪,600多呢,上边的两步超过多少就得再建第三个加油站了哪,就是超过500+500/3,也就是耗油最多是汽车的承受能力,即500升,所以分3次,除以3,就是500+500/3,超过这个就得再建设加油站了,前加油站就得需要500+500,也就是1000升,依次类推,不难推出一个整体

下面再建,你就把500+500/3看作一个整体来看,所以,程序就出来了,我也是经过仿佛的调试,所以有点乱,呵呵。

   main()
  {
   float sum=500,s=500,t;
   int k=1;
   while(s<1000)
   {
    k++;
    t=500/(2*k-1);
    s=s+t;
    }
   算到这里以后,循环完毕,肯定这个路程超过1000了,所以现在要求出这个不到1000的时候的直,就是
  s=s-t;
  这个时候的s就是最大化的时候数值,然后再看零头
就是
  t=1000-s;就是除去最大化的,剩下的
  最后建设站数就是K的值,耗油量就是
(k-1)*500,就是把最大化那个乘上,还有那个零头肯定不是最大化的,所以就是t*(2*k-1),就是剩下的公里零头就是耗油量,但是要走(2×k-1)次,所以用乘法,加在一起就是总耗油量,呵呵,作完了这道题。
鸿运当头,恭喜您获得 1 金币
公元6月6日,举步维艰呀,昨天穿越沙漠问题在有原代码就是有答案的基础上,还研究了一天才弄明白,真不知道是不是自己太笨了,这样的速度简直就是蜗牛的速度,而且,人家的回帖基本上没有看太明白,还得努力呀!磨刀不误砍柴工,我想,把基础知识打牢固一点也好,毕竟我研究电脑没有什么功利性的目的,只是爱好,想把它研究透彻,尤其是程序,它都是一环套一环的,今天可能研究的时间不是很多,但是我想我会抓紧时间的.

   通过前一段时间,以及沙漠这道题,我想我对算法还不是很了解,真的,研究透彻的人,我想在作题目的时候他就会有一种算法直觉,我现在会的算法,就是,穷举,迭代,还有就是一组数列找出,最大直,最小直,还有就是由从大到小,或者从小到大排序,还有很多算法我都没有掌握,还有就是解决实际数学问题的能力不强,很多题目就是你用方程或者数学的方法都不会,试问你如何用c解决呢,所以还得锤炼自己的解决数学,尤其是一些经典智力题目的能力,今天,就做这种能力,我开始做经典c程序100例,今天也没什么要求,能做多少做多少,但是,要求做一个,会了不是目的,还要写清楚为什么会的,如何会的,这样才能吸收知识.好了,开始吧
经典例子第一例,原题,就是有1,2,3,4用这4个数字,

组成一个三位数,能组成多少个?条件是,不能有重复的

数字,就是如果各位上有1了,那么其他位置上就不许有1

了.可以用一个三重循环来控制,每重都是从1循环到4,

这样,
    m=0;
    for(i=1;i<=4;i++)
      for(j=1;j<=4;j++)
        for(k=1;k<=4;k++)
          要是可以有数位上允许有相同的数字,就开

始记数就可以了,但是它要求数位上的数字各不相同,

好,我们就用一个if来控制.
         if(i!=j&& j!=k&& i!=k)
            m++;
  这样有多少个,就一目了然了,如果要输出来所有的数

的话,就是
         m=0;
    for(i=1;i<=4;i++)
      for(j=1;j<=4;j++)
        for(k=1;k<=4;k++)
          if(i!=j&& j!=k&& i!=k)
              printf("%d%d%d  ",i,j,k);
   再加一个条件,如果要求5个一换行,可以这样:

      m=0;n=4;
    for(i=1;i<=4;i++)
      for(j=1;j<=4;j++)
        for(k=1;k<=4;k++)
          if(i!=j&& j!=k&& i!=k)
             { printf("%d%d%d  ",i,j,k);
                  n++;
                if(n%4==0)
                  printf("/n");
               }
第二道:
     奖金和利润的关系,利润有10万元,奖金提成利润

的10%,如果奖金超过10万元,在20万元之间,超过的部分

按照7.5提成,
1万---10万---20万----40万----60万---100万--以上
    10%    7.5%    5%      3%      1.5%    1%
                 
  要求输入利润,计算出奖金来
  算法:
         先把利润正好是边界的直依次求出来,   

利润正好是10万的时候的奖金数:   a1=10*10%

正好是20万的奖金数,分两部分,
10万的奖金数和超过10万的部分:   a2=a1+10*7.5%
                  
正好是40万的奖金数:          a3=a2+20*5%

正好是60万的奖金数:          a4=a3+20*3%

正好是100万的奖金数:         a5=a4+40*1.5%

然后scanf一个数值,N
用if判断来选择不同的求法:

       if(n<=10)
        n*10%
        if(n<=20)
       a1+(n-10)*7.5%
        if(n<=40)
       a2+(n-20)*5%
        if(n<=60)
        a3+(n-40)*3%
        if(n<=100)
        a4+(n-60)*1.5%
        if(n>100)
        a5+(n-100)*1%
经典百例之例三,有一个数量,这个数加上100,正好是一个完全平方数,再加上168,还是一个完全平方数。
   这道题我看到以后总体原则确定为就用穷举法,就是 从4开始循环到一个大数,比如1000,然后,看加上100和268之后,两个数是否是完全平方数,如何判断一个数是否是完全平方数呢,
  算法我是这样设计的,用它的一半作为除数,循环去除它,什么时候商和除数相等,什么时候可以,而且,不相等,有余数的时候,它也认定为相等,所以我采用数据类型里边的float,下面是源程序。

    float wanquan(flaot m)
   {
     float i,n,k=0;
     for(i=2;i<=m/2;i++)
      {
        n=m/i;
       if(n==i)
        k=1;
       }
      return(k);
    }
    main()
  {
    float wanquan(float m);
    float i,n,m;
    for(i=4;i<=1000;i++)
    { m=wanquan(i+100);
     n=wanquan(i+268);
      if(m==1&&n==1)
       printf("%f",i);
      }
}
我的想法是构造一个专门判断是否完全开方的函数,用1,0的返回值来判断,像这种判断函数必须得有两个返回值,一个是符合标准,一个是不符合标准,也就是1和0。
   后来我看到了正确答案,原来有一个函数是专门求平方的,调用一个math.h头文件就可以了
    # include"math.h"
  main()
{
   float i,m,n;
   for(i=4;i<=1000;i++)
    {
      m=sqrt(i+100);
      n=sqrt(i+268);
     if(m*m==i+100 && n*n=i+268)
      printf("%f\n",i);
     }
}

TOP

百例程序之第四例:就是输入几月几日,然后程序告诉你,这是一年内的第几天,这个算法就是把每月的天数都分别求出来,然后再把零的日子数加上就可以了,可以把每月的天数放在一个数组中,为了理解方便,我们a[1]定为1月,把a[0]空出来。
   main()
{
   int a[100],m,n;
   scanf("%d%d",&m,&n);
   a[1]=31;
   a[2]=a[1]+28;
   a[3]=a[2]+31;
   a[4]=a[3]+30;
   a[5]=a[4]+31;
   a[6]=a[5]+30;
   a[7]=a[6]+31;
   a[8]=a[7]+31;
   a[9]=a[8]+30;
   a[10]=a[9]+31;
   a[11]=a[10]+30;
   a[12]=a[11]+31;
   printf("%d",a[m-1]+n);
}
还要考虑程序的中断问题,就是m的值必须是1到12之间,n的值是1到31之间,如果是2月,必须n的值是不能大于28,这些都要控制上,我想用if 就可以了
   
main()
{
   int a[100],m,n;
   aa scanf("%d%d",&m,&n);
   if(m>12||m<1||n<1||n>31)
    goto aa;
   if(m==2&&n>28)
    goto aa;
   a[1]=31;
   a[2]=a[1]+28;
   a[3]=a[2]+31;
   a[4]=a[3]+30;
   a[5]=a[4]+31;
   a[6]=a[5]+30;
   a[7]=a[6]+31;
   a[8]=a[7]+31;
   a[9]=a[8]+30;
   a[10]=a[9]+31;
   a[11]=a[10]+30;
   a[12]=a[11]+31;
   printf("%d",a[m-1]+n);
}

TOP

早晨刚把这道题作完,现在天亮的早了,5点就亮了,上边的代码我没有调试,还有我没有考虑到闰年的情况,什么是闰年我都给忘了,还有就是goto的用法,我没看过,只是书上具体介绍过,我就用了,不知道对不对,刚才我又看了看百例,觉得有很多,我都会了,,但是为了全面巩固,我决定一个例子不差的坐下来。一旦发现有不会的新知识,要总结出来并且掌握它,我自我感觉我学的挺慢的了,工作上的事情,还有恋爱的事情,人际关系的事情,总让我分心,昨天一天,才作了几个例子亚?3个,而且我都26岁了,不说了,只有努力,不要找借口。

TOP


当前时区 GMT+8, 现在时间是 2008-11-22 13:10 苏ICP备06039509号 当当网

Designed By 17DST Discuz! Support Team | Discuz!支持团队