题目链接:https://csacademy.com/contest/archive/task/reconstruct-sum
题目大意:每个数都可以表示成两个加数的和,例如15 = 6 + 9,或者15 = 11 + 4,对比这两种的进位能够发现,前者最低位是有进位的,后者是没有的。现在给出一个数字S < 1e18,以及长度为s的位数-1的01序列。这个序列从前到后表示从最低位开始,如果为1,表示两个加数在这一位是有进位的,否则是没有的。现在问,满足条件的加数情况多少种。6 + 9 和9 + 6是不同的。
解题思路:从最低位开始,每一位单独考虑,然后相乘。对于当前数字s来说,设 u = s % 10,同时将s /= 10, 若 ai = 1, 则该位为 可选方案为 9 - u种,并且将s减一;若为0,则为u+1 种;若该位为-1则说明不存在解。需要注意的是,若该位为1,并且高位为0,则说明高位实际上是9,因此应当将高位的进位减去1(显然9+1一定会有进位),那么高位进位就变成了0,然而这个时候实际上高位是有进位的,因此设置一个标志变量表示这种情况:高位虽然不用进位,但是它会在前一个进位的作用下产生进位,并且,对于高位的连续的0来说,这个都是成立的;若该位为0那么我们要看一下标志变量以及高位的值。如果标志变量为真高一位为9,那么显然我们需要继续将上一位的进位-1并且标志变量依然为真,否则标志变量到此就无效了。
比较繁琐,但是并不复杂,代码:
1 unsigned long long s; 2 int a[maxn]; 3 4 void solve(){ 5 unsigned long long ans = 1; 6 int j = 1; 7 bool flag = false; 8 while(s >= 10){ 9 int u = s % 10; 10 s /= 10; 11 if(a[j] == 1){ 12 ans *= 9 - u; 13 if(s % 10 == 0) { 14 a[j + 1] -= 1; 15 flag = true; 16 } 17 else flag = false; 18 s -= 1; 19 } 20 else if(a[j] == 0){ 21 ans *= u + 1; 22 if(flag && s % 10 == 9) 23 a[j + 1] -= 1; 24 else flag = false; 25 } 26 else { 27 ans = 0; break; 28 } 29 j++; 30 } 31 if(s) ans *= s + 1; 32 printf("%lld ", ans); 33 } 34 int main(){ 35 scanf("%lld", &s); 36 int n = 0; 37 ll x = s; 38 while(x){ 39 n++; 40 x /= 10; 41 } 42 for(int i = 1; i < n; i++) scanf("%d", a + i); 43 solve(); 44 }
题目:
Reconstruct Sum
Memory limit: 128 MB
A number SS can be written in S+1S+1 ways as a sum of two non-negative integers AA and BB.
When adding two integers, a carry is a digit that is transferred from one column of digits to another column of more significant digits. It is part of the standard algorithm to add numbers together by starting with the rightmost digits and working to the left. For example, when66 and 77 are added to make 1313, the "3""3" is written to the same column and the "1""1" is carried to the left.
You know which columns of digits generate a carry when performing the addition A+B=SA+B=S. Find the number of solutions.
Standard input
The first line contains a single integer SS.
The second line contains a binary array of length equal to the number of digits of SS minus 11 (the most significant column doesn't generate a carry). These values correspond to the columns of digits, starting with the rightmost one. A column that generates a carry is represented by 11, one that doesn't by 00.
Standard output
Print the answer on the first line.
Constraints and notes
- 10 leq S leq 10^{18}10≤S≤1018
Input | Output | Explanation |
---|---|---|
15 0 |
12 |
From the 1616 total ways of choosing AA and BB, 44 are invalid:
All these generate a carry, when they shouldn't. |
15 1 |
4 |
The valid pairs are the invalid ones from the previous example. |
140056 1 0 1 1 0 |
10800 |
|
140056 1 0 1 0 1 |
0 |