A+B问题

来自"NOCOW"

跳转到: 导航, 搜索
 这篇文章可以证实是由NOCOW用户原创,不存在任何版权争议。
 本文作者同意以GNU FDLCC-by-saGNU 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++实现的

  1. 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、位运算 迭代版:

  1. 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; } 递归版:

  1. 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),自己写数字输入输出可能也是比较困难的地方。

另外上面要注意的问题,也可能会让人不小心出错。

[编辑] 评价及扩展

这道题是为了测试输入输出和提交方法用的,没有多少技术含量。

USACOYour Ride Is Here还考察了基本的语法,目的还有测试做题的人会不会编程。而Life, the Universe, and Everything同时也为BrainF**k等语言的使用者考虑了,是一道不需要数字输入输出,什么语言都可以很简单的做出来的题目。另外还有一个经常用来测试的程序:输出Hello World,但是Hello World的程序没有输入部分。

而这道题目的扩展通常只是加入数据范围之类的陷阱,用其他的进制计算高精度数支持操作符之类的。第二、三条通常只是练习题目,最后一条在编译器、解释器之类的很多地方都比较有用,但是这种程序绝大部分都不是关于A+B的内容。

[编辑] 题目编号

[编辑] 参见

[编辑] 所用算法和数据结构

无。

[编辑] 相关题目

个人工具