牛客小白月赛23 E-A+B问题[签到]
https://ac.nowcoder.com/acm/contest/4784/E
时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 262144K,其他语言524288K
64bit IO Format: %lld
题目描述
经典的A+B问题描述如下:
从标准输入流输入两个整数 A 和 B,请你求出这两个数字的和。其中 A 和 B 都在32位有符号整数能存储的范围内。
下面是一份AC代码:
#include < iostream >
using namespace std;
int main()
{
int a, b;
cin >> a >> b;
cout << a+b;
return 0;
}
现在已知这个程序输出的结果是 c,请问有多少种可能的输入数据?
输入描述
一行,仅包含一个整数 c ,这个整数的值在32位有符号整数的存储范围内。
输出描述
一个数,表示可能的输入数据的情况数
样例输入
1
样例输出
4294967296
说明
以下输入数据都可以让该程序输出1
1 0
2 -1
-5 6
0 1
-2147483647 -2147483648
想要使上述程序输出1,总共有4294967296种可能的输入
分析
这题真可谓是『おもしろい』,给出完整AC代码的题可是真不多见。
题目是A+B,却直接给出标程,反向操作,给出输出,求输入。
对于出题人的那脑洞,老夫只能说,佩服,佩服。
怎么说呢,看到这题的时候,我也是会心一笑,虽然是道签到,但并不妨碍它好玩。
假·分析
少见的是,这题并没有显式给出数据范围,而是隐含在了题干当中——“32位有符号整型”,
也就是我们常说的 int .
按照正常的思路,我们先让A=C,B=0,此时[A++,B–],[A–,B++]才能维持相加结果不变(C).
向内,A,B相遇时停止,向外,任何一个遇到边界停止。随后结果×2,表示A,B翻转。
看似完美的思路,遇到了"说明"中的最后一个样例就歇菜了,因为计算溢出也包括在内,只要按照C++的规范能算出A+B==C的输入都合法。
这也意味着,这不能通过简单的数学计算得出答案。
真·分析
既然都说是签到了,那就得有个签到的亚子,当我看到AC人数在几分钟内猛增几百的时候,我就有了一个大胆的想法——也许这题,跟输入无关。
我们不妨这样想,A+B=C,则A=C-B,C是定值,那么对于任何一个A,是否都存在一个B与之对应?
答案是肯定的,我还没见过哪个加减法无解的 ,那么只需要确定A的取值数,就能确定[A,B]输入数
那么A有多少种取值呢?毋庸置疑,32位有符号整数,32bits的所有组合,即2^32,namely,1LL<<32
也就是4294967296,这好像已经写在"说明"里了…狂妄的出题人,赤裸裸的挑衅
"Talk is Cheap. Show me the Code."
#include<stdio.h>
int main(void)
{
int c;
scanf("%d", &c);
printf("4294967296\n");//过分了,这题
return 0;
}