学习编程时,“明知故犯”是有益的:起码你知道了错误的现象。这样,当真的不小心犯错时,可以通过现象猜测到可能的原因。
大多数的算法竞赛包含如下一些相同的“游戏规则”。
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进行异或运算,变量的值保持不变。因为原变量的值的二进制为若为1,1与0异或后为1,原变量的二进制位若为0,0与0异或后为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,注意这里的a,b为最初时的变量的值。
接着执行第三条语句a=a^b。由于a的值为a^b,b的值为(a^b)^b,所以第三条语句相当于a=(a^b)^(a^b)^b,即a的值等于(a^a)^(b^b)^b,结果为b,a得到了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>