CF952F 2 + 2 != 4 题解
超级毒瘤愚人节玄学题???
luogu传送门
题意简述
按照样例的方式计算题目给出的表达式的值???
\(\texttt{SOLUTION}\)
首先我们来看一下样例:
- 样例一:\(8-7+6-5+4-3+2-1-0=0=0(\text{正常运算中表达式的值})+0\)
- 样例二:\(2+2=-46=4(\text{正常运算中表达式的值})-5\times 10^1\)
- 样例三:\(112-37=375=70(\text{正常运算中表达式的值})+3\times 10^2\)
看到这我们发现 \(0,50,300\) 这些数都很有规律,于是开始思考:他们是怎么来的呢?
首先看样例一的式子,它的值为 \(4\) ,十分正确,再对比样例二和样例三。
发现只有样例一中的 \(+\) 号和 \(-\) 号个数相同。
于是我们下意识的从符号下功夫。
作为一个合格的 \(\text{OIer}\) 你一定对字符的 \(\texttt{ASCII}\) 十分熟悉吧。
我们翻了翻 \(\texttt{ASCII}\) 编码表(大雾)发现 \(-\) 的 \(\texttt{ASCII}\) 编码为 \(45\) ,个位数为 \(5\), \(+\) 的 \(\texttt{ASCII}\) 编码为 \(43\) ,个位数为 \(3\)。
然而,样例二却是 \(-\) \(\color{red}5\) \(\times 10^1\) ,样例三是 \(+\) \(\color{red}3\) \(\times 10^2\),加红的数刚好与 \(+\) 号 \(-\) 号的 \(\texttt{ASCII}\) 的个位数反过来了,而数之前的符号也与 \(+\) \(-\) 反过来了。
又发现
- \(10^1\) 中的 \(1\) 就是 \(2\) (\(+\) 号后数字)的位数。
- \(10^2\) 中的 \(2\) 就是 \(37\) (\(-\) 号后数字)的位数。
于是我们就猜出了结论:按照正确计算方法计算完毕原式的值后,对于每个符号 \(+\), 减去 \(3\times 10^{+ \text{后数字的位数}}\)。对于每个符号 \(-\), 加上 \(3\times 10^{- \text{后数字的位数}}\)。
快速的打完了代码。
A?
A了。
真是不可思议!!!
至于为什么 \(+\) 是减去 “ \(3\) ” 而 \(-\) 是加上 “ \(5\) ”,参考了其他题解,原来并不是因为把 \(\texttt{ASCII}\) 的个位数反过来,而是把符号也当做数字来看,\(0\) 的 \(\texttt{ASCII}\) 为 \(48\) 而 \(|43-48|=5\),\(|45-48|=3\) ,所以 \(+\) 是减去 “ \(3\) ” 而 \(-\) 是加上 “ \(5\) ”。
\(\texttt{AC CODE}\)
#include
#define IN inline
const int N=100010;
int n,ans;
char str[N];
int main()
{
scanf("%s",str+1);
n=strlen(str+1);
int i=1;
while(str[i]>='0'&&str[i]<='9'&&i<=n)//第一个数没有符号,特判
{
ans=ans*10+str[i]-'0';//存储每个符号之后的数字的值
++i;
}
while(i<=n)
{
if(str[i]=='+')
{
int ws=0,num=0;
++i;
while(str[i]>='0'&&str[i]<='9'&&i<=n)
{
++ws;//存储每个符号之后的数字位数
num=num*10+str[i]-'0';//存储每个符号之后的数字的值
++i;
}
ans=ans-5*std::pow(10,ws)+num;
}
else if(str[i]=='-')
{
int ws=0,num=0;
++i;
while(str[i]>='0'&&str[i]<='9'&&i<=n)
{
++ws;//存储每个符号之后的数字位数
num=num*10+str[i]-'0';//存储每个符号之后的数字的值
++i;
}
ans=ans+3*std::pow(10,ws)-num;
}
}
printf("%d",ans);
return 0;
}
\(\text{P.S}\). 这题难度严重恶评,这思维难度至少紫题吧!!!