T1
牛牛刚学习了输入输出,他遇到了一道这样的题目。
输入2个整数a和b 保证输入的a和b在long long范围之内,即满足 -9223372036854775808 <= a, b <= 9223372036854775807 计算a+b的值,即这两个数字的和。 如果a+b在long long范围之内,即满足 -9223372036854775808 <= a + b <= 9223372036854775807 那么输出一行一个整数表示a+b的结果。 如果a+b不在long long范围之内,即越界了,那么输出"hello, %lld\n",包含引号。 具体可以参见样例。
题解:题目虽然简单,但是还是值得一做。
关于判断a+b,
1.a、b异号或者一个是0,那么输出a+b即可。
反之,用高精判断。
高精比较麻烦的。
如果上限是C,A+B<=C等价于A<=C-B即可。
下限同理可以处理。
甚至有人利用溢出原理。
a、b同号,如果a+b不是同号,那么就溢出了。
然后,输出"hello, %lld\n"怎么办?
考察转义。
输出",就输出\"
输出%,就输出%%
输出\,就输出\\
所以,
printf("\"hello,%%lld\\n\"");
T2T3略
T4:
合法括号序列 键盘上有左括号(,右括号),和退格键-,共三个键。 牛牛希望按键n次,使得输入的字符串恰好一个合法的括号序列。 每按一次左括号(,字符串末尾追加一个左括号( 每按一次右括号),字符串末尾追加一个右括号) 每按一次退格键-,会删掉字符串的最后一个字符, 特别的,如果字符串为空,牛牛也可以按退格,但是什么都不会发生。 输出方案数对p取模,注意p可能不是质数。
注:只要按键方法不同,就是不同的方案,即使得到的序列一样。对于所有数据: 2 <= n <= 1000, 2 <= p <= 1000030分: n <= 4070分: n <= 100
题解:
可以发现(我想不到),
方案数和具体括号序列无关,只和最终括号序列长度有关。
因为就这么多剩下的,那么管他是什么字符呢?
所以问题分成两个部分。
枚举括号序列的长度2k,
1.计算出来对于每一个长度2k,合法的括号序有多少个。
2.对于长度为2k的序列,方案数有多少。
乘法原理再加法原理即可。
对于1,是一个卡特兰数。
可以看:
具体证明,可以直接转化成火车出栈顺序,或者走到(i,i)方案数。
预处理组合数。递推或者直接C(2n,n)-C(2n,n-1)
对于2,设f[i][j]表示,前i次操作后,序列长度为j的方案数。
f[i][j]=f[i-1][max(0,j-1)]+2*f[i-1][j+1]
为什么删除的操作转移有一个2
因为我们的f[i][j]其实也是一个可以变化成任意一个的合法序列,所以每个位置的填法要么是),或(,唯一确定的。
但是把这个位置删了,那么就可以“反悔”地把上一位随便填。