【愿成其身】[12]从交换输出谈起 – 黑盒的漏洞

本篇文章讲解题目:交换输出

推荐先独立进行解题尝试,然后再阅读本篇讲解!


这也是一道经典问题,今天就从它谈起。

$a \rightleftharpoons b$

首先分析题目,下面这种写法肯定是错的。

1
2
3
4
5
6
7
8
9
#include<stdio.h>
int main() {
	int a,b;
	scanf("%d %d",&a,&b);
	a=b;
	b=a;
	printf("%d %d\n",a,b);
	return 0;
}

因为在a=b的时候,a的值已经被替换成b了。


这个时候我们想,若把a的值提前记录下来便可以了。

也就是int t=a;a=b;b=t;


事实上,还有一种更为酷炫的不借助其它变量的写法如下。

1
2
3
a+=b;
b=a-b;
a=a-b;

也就是直接把b的值存在a里面,然后a-b便是a的值——赋值给b,然后此时a-b便是b的值——赋值给a。


同样按照这种思路,有依靠于二进制运算的更为酷炫的写法:

1
2
3
a^=b;
b^=a;
a^=b;

因为对计算机来说二进制更为快速,所以这种写法也是更省时间的。


下面还有一个最终版本。

在前面说过,黑盒测试是给输入数据然后比较输出数据是否一样,而这一道问题的输出是a和b交换值之后输出a和b的值。

那么我们便可以提交如下代码:

1
2
3
4
5
6
7
#include<stdio.h>
int main() {
    int a,b;
    scanf("%d %d",&a,&b);
    printf("%d %d\n",b,a);
    return 0;
}

同样是符合题意的一种代码。


在分析这道题的过程中。

  1. 首先,根据最简单的题意我们写出了一份代码。
  2. 然后,根据数学知识做出了优化(所用空间减少)。
  3. 之后,根据同样地思想用二进制优化了计算过程(所用时间减少)。
  4. 最后,依照黑盒测试的特点写出了最简代码。

当然,对于这一题来说,即使是最初的代码所用的时间与空间也是非常少的,所以优化对这一题来说也许没必要。

但是这种思想是我们应该学习的,正是在这种优化中,自身的编码能力及思考问题的能力会有显著的提高。

而实际比赛中,我们也可以根据题意,在符合要求的前提下,选取那个最容易想出且容易写成的方案来实现。

该内容采用 CC BY-NC-SA 4.0 许可协议。

如果对您有帮助或存在意见建议,欢迎在下方评论交流。

最后更新于 2016-08-26 16:00:45