从零学习算法竞赛1: 变量交换

4 篇文章 0 订阅
3 篇文章 0 订阅

          学习编程时,“明知故犯”是有益的:起码你知道了错误的现象。这样,当真的不小心犯错时,可以通过现象猜测到可能的原因。

         大多数的算法竞赛包含如下一些相同的“游戏规则”

         1.选手程序的执行是自动完成的,没有人工干预。不要在用户输入之前打印提示信息(例如“Please input n:”),这样不仅不会为程序赢得更高的“界面友好分”,反而会让程序丢掉大量的(甚至所有的)分数——这些提示会被当作输出数据的一部分。

          2.不要让程序“按任意键退出”(例如,调用system(“pause”),或者添加一个多余的getchar()),因为有人来按”任意键“的。不少早期C语言教材在程序最后添加这样一条语句来“观察输出结果”,但注意千万不要在算法竞赛中这样做。

        3.最容易忽视的是输出格式;在很多情况下,输出格式时非常严格的,多一个或者少一个字符都是不可以的!

        4.在算法竞赛中,每行输出均以回车符结束,包括最后一行。除非特别说明,每行的航首不应有空格,但行末通常可以有多余空格。另外,输出的每两个数或者字符串之间应以单个空格隔开。

       5.算法竞赛中的程序应当只做三件事:读入数据、计算结果、打印输出。不要打印提示信息,不要在打印输出后“暂停程序”,更不要尝试画图、访问网络等与算法无关任务。

       6.尽量用const关键字声明常数。

      7。在一般情况下,你的程序不能直接读取键盘和控制屏幕:不要在算法竞赛中使用getch(),getche(),gotoxy(),clrsrc()等函数。在算法竞赛中不要使用头文件conio.h

       变量交换

      

输入两个整数a和b,交换二者的值,然后输出。
样例输入:
824 16
样例输出:
16 824

分析:按照题目所说,先把输入变量存入a和b,然后交换。如何交换两个变量?最经典的方法是三变量法:

        程序1:三变量交换法:

    

#include<stdio.h>
int main()
{
   int a,b,t;
   scanf("%d%d",&a,&b);
   t=a;
   a=b;
   b=t;
   printf("%d %d\n",a,b);
   return 0;
}
   运行结果:

  

注:三变量交换法使用范围广,推荐使用。

    程序2:算术加减法
   

#include<stdio.h>
int main()
{
   int a,b;
   scanf("%d%d",&a,&b);
   a=a+b;
   b=a-b;
   a=a-b;
   printf("%d %d\n",a,b);
   return 0;
}
      这个方法看起来很好,少了一个变量,但实际上很少用,因为适应范围很窄,也存在一定问题: 万一数据溢出了怎么办?;只有定义了加减法的数据类型才能采用此方法。怎么办?

       程序3:异或运算法

      

       用异或运算进行交换

      异或运算符^也称XOR运算符。它的运算规则是:如果参加运算的两个二进制为相同,则结果为0(假);相异为1(真)。

      性质1:变量自己与自己进行异或运算结果肯定为0,。因为参加异或运算的双方都是变量自己的值,各个二进制为都是相同的,故各位运算的结果都为0.

      性质2:一个变量与0进行异或运算,变量的值保持不变。因为原变量的值的二进制为若为110异或后为1,原变量的二进制位若为0,00异或后为0.可见不管二进制是1还是0,都保持不变。可见不管二进制是1还是0,都保持不变,故而变量的值未曾改变。

       按照异或运算的有关性质,可以设计算法如下:

               a=a^b;

               b=a^b;

               a=a^b

       执行第一条和第二条语句的效果相当于执行b=(a^b)^b,b=(a^b)^b等价于b=a^(b^b)。因为同一个变量与本身异或,结果为0,所以b^b结果为0.进而b=a^(b^b)就为b=a^0,又因为一个变量与0异或,变量的值保持不变,所以a^0异或后结果为a。可见,当第一条和第二条语句执行后,b变量已经得到了原变a量的值;对于a变量而言,它的值为a^b,注意这里的ab为最初时的变量的值。

        接着执行第三条语句a=a^b。由于a的值为a^bb的值为(a^b^b,所以第三条语句相当于a=(a^b)^(a^b)^b,a的值等于(a^a^(b^b)^b,结果为ba得到了b原来的值。

#include<stdio.h>
int main()
{
   int a,b;

   scanf("%d%d",&a,&b);
   a=a^b;
   b=a^b;
   a=a^b;
   printf("%d %d\n",a,b);
   return 0;
}
        程序4:压栈出栈法
       push(x);
       push(y);
       pop;
       pop;<span style="background-color:rgb(255,255,255)">
</span>
      程序5:递归法
     <pre name="code" class="cpp">#include<stdio.h>
void fun()
{
   int a,b;
   
   if(scanf("%d",&a)!=EOF)
      fun();
   printf("%d\n",a);
}
int main()
{
   fun();
   return 0;
}
       小结<span style="background-color:rgb(255,255,255)">:介绍多种种算法并不是要应用到实践当中,因为有些方法具有局限性,仅仅是为了发散思维,展示程序设计的魅力。从中可以看出,数学
中的小技巧对程序设计而言具有相当的影响力,运用得当会有意想不到的神奇效果。而从实际的软件开发看,三变量算法
无疑是最好的,能够解决任意类型的交换问题。</span> 




                
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值