A+B问题
来自"NOCOW"
这篇文章可以证实是由NOCOW用户原创,不存在任何版权争议。 本文作者同意以GNU FDL、CC-by-sa和GNU LGPL(如果适用)三种版权发布此文章(不包括翻译文章中属于原始所有者的部分版权)。 如果你修改了这篇文章并且不同意用GNU FDL以外的版权发布,可以换一个版权模板或者移除此模板。
A+B问题是一个非常简单的程序设计问题。通常是在线题库用来让人测试提交和输入输出方法的题目。
- 这是URAL Volume 1中的OI题目A+B Problem的介绍及题解,参见翻译,C语言代码,Pascal语言代码。
- 这是SGU Volume 1中的OI题目A+B Problem的介绍及题解,参见翻译,C语言代码,Pascal语言代码。
- 这是VIJOS Volume 1中的OI题目A+B Problem的介绍及题解,参见C语言代码,Pascal语言代码。
- 这是浙江大学OJ Volume 1中的OI题目A+B Problem的介绍及题解,参见翻译,C语言代码,Pascal语言代码。
- 这是北京大学OJ Volume 1中的OI题目A+B Problem的介绍及题解,参见翻译,C语言代码,Pascal语言代码。
目录 |
[编辑] 一般描述
输入两个数A和B(一般是在长整范围内的正整数,也就是小于2147483648),输出A+B。
[编辑] 解决方法
这道题是非常简单的,只要用所用的语言的功能读入两个数,求和并输出就可以了。
[编辑] 范例程序
[编辑] Pascal
var a,b:longword; begin readln(a,b); writeln(a+b) end.
[编辑] C++
#include<iostream> int main(){ unsigned long a,b; std::cin>>a>>b; std::cout<<a+b<<std::endl; return 0; }
这两个程序适用于所有输入两个0到2147483647之间的十进制数的,使用标准输入输出的A+B问题。
“不用'+'操作符解决A+B问题”是一个很有趣的研究课题,总结了一下,大致有以下几种方法
1、用'-'代替'+',可以通过计算-(-a-b)或a---b等等来求
2、利用对数函数的性质,鉴于两数乘积的对数等于两数对数的加和,所以可以把'加'隐藏到'乘'里。下面的程序以e为底,即ln(e^a * e^b) using System; public class sum {
public static void Main() { string[] tokens = Console.ReadLine().Split(' '); int a = int.Parse(tokens[0]); int b = int.Parse(tokens[1]); Console.WriteLine(Math.Log(Math.Exp(a)*Math.Exp(b),Math.E)); }
}
3、内嵌汇编代码 可以使用汇编来完成+的过程,但是C#貌似不能内嵌汇编代码(可以考虑写&调用DLL),C++可以借助“_asm”关键字内联汇编,下面的代码是用C++实现的
- include <cstdio>
int main () { int a; int b; scanf("%d %d", &a, &b); __asm{
mov eax, dword ptr a add eax, dword ptr b mov dword ptr a, eax
} printf("%d\n", a); return 0; }
4、位运算 迭代版:
- include<iostream.h>
main(){ int x,y,i; for(cin>>x>>y,x=~x;x^~0;x^=y^=x^=y) for(y^=i=1;y&i;y^=i<<=1); cout<<~y; } 递归版:
- include <iostream.h>
int s(int a, int b){ return !a||!b ? a|b : s((a&b)<<1,a^b); } main(){ int a, b; cin >> a >> b; cout << s(a,b); }
5、向CPU发送机器码 type pinteger = ^integer; var a, b: integer; p:procedure; instr:array [1..11] of byte = ($8B, $45, $08, $8B, $55, $0C, $8B, $12, $01, $10, $C3); procedure sum(a, b: pinteger); stdcall; begin p(); end; begin p:=@instr; readln(a, b); sum(@a, @b); writeln(a); end.
[编辑] 要注意的问题
在有的版本的A+B题目中,虽然输入的a和b都在长整的范围之内,结果a+b的值不一定也在这个范围。这时候就要使用无符号的长整数,也就是pascal的longword或者cardinal、c++的unsigned long。如果这道题目的数据也允许负数,就要使用64位整数,pascal的int64以及c++的long long。当然也可以特殊处理,不过比较麻烦。
[编辑] 难点
这个题库可能会使用特殊的输入输出方法(例如文件输入),也可能要求提交的时候加入一些附加信息,如果没在这个题库做过题目也没有看帮助,或者以前完全没有使用文件的经验,这可能就是难点。
另外对于一些不自带数字输入输出功能的语言(例如BrainF**k),自己写数字输入输出可能也是比较困难的地方。
另外上面要注意的问题,也可能会让人不小心出错。
[编辑] 评价及扩展
这道题是为了测试输入输出和提交方法用的,没有多少技术含量。
USACO的Your Ride Is Here还考察了基本的语法,目的还有测试做题的人会不会编程。而Life, the Universe, and Everything同时也为BrainF**k等语言的使用者考虑了,是一道不需要数字输入输出,什么语言都可以很简单的做出来的题目。另外还有一个经常用来测试的程序:输出Hello World,但是Hello World的程序没有输入部分。
而这道题目的扩展通常只是加入数据范围之类的陷阱,用其他的进制,计算高精度数,支持操作符之类的。第二、三条通常只是练习题目,最后一条在编译器、解释器之类的很多地方都比较有用,但是这种程序绝大部分都不是关于A+B的内容。
[编辑] 题目编号
[编辑] 参见
[编辑] 所用算法和数据结构
无。