Contest Round #451 (Div. 2)F/Problemset 898F Restoring the Expression

本文介绍了一种解决特定数学谜题的方法,通过去除等式中的符号并重新组合数字来还原原始等式。文章详细阐述了解题思路,并给出了具体的实现代码。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题意:

有一个a+b=c的等式,去掉两个符号,把三个数连在一起得到一个数

给出这个数,要求还原等式,length <= 1e6

三个数不能含有前导0,保证有解

 

解法:

铁头过题法,分类然后各种判断

我分了5种情况

0.开头字符为0, 那么结果一定是0+a=a的形式

然后4种情况

1.len(a) >= len(b) 且 len(c) == len(a)

2.len(a) <= len(b) 且 len(c) == len(b)

3.len(a) >= len(b) 且 len(c) == len(a) + 1

4.len(a) <= len(b) 且 len(c) == len(b) + 1

前两种(没有进位)判断的情况:

(1)三个数如果长度不为1,那么最高位不能为0

(2)len(a) != len(b) 时, 若max(a, b)的最高位为x,

 则c的最高位,应该为x或者x+1

(3)满足上面两种情况,开始检验a+b的每一位与c的每一位是否相等

后两种(有进位)判断的情况:

(1)三个数如果长度不为1,那么最高位不能为0

(2)c的最高位必须是1

(3)满足上面两种情况,开始检验a+b的每一位与c的每一位是否相等

 

时间复杂度未知,但是实际运行效果,时空复杂度都是超赞的!

(整理了一下代码似乎精简过度影响了可读性了...)

 1 #include <stdio.h>
 2 #include <string.h>
 3 
 4 int n;
 5 
 6 char s[1000010];
 7 
 8 int i, j, k, p, l, r;
 9 
10 int print() {
11     int i = 1;
12     for (; i <= l; i ++)
13         putchar(s[i]);
14     putchar('+');
15     for (; i <= r; i ++)
16         putchar(s[i]);
17     putchar('=');
18     for (; i <= n; i ++)
19         putchar(s[i]);
20     return 1;
21 }
22 
23 int check(int s1, int s2) {
24     for (int i = s1, j = s2, k = n, t = 0; k > s2; k --) {
25         if ((s[i] + s[j] + t - 96) % 10 != s[k] - 48) 
26             return 0;
27         t = (s[i] + s[j] + t - 96) / 10;
28         i --, j --;
29         if (i <= 0) i = 0;
30         if (j <= s1) j = 0;
31     }
32     return 1;
33 }
34 
35 int judge() {
36     if (l + 1 != r && s[l + 1] == '0') return 0;
37     if (p) {if (s[r + 1] != k) return 0;}
38     else if (i != j && (k != s[r + 1] && k + 1 != s[r + 1])) return 0;
39     if (!check(l, r)) return 0;
40     return print();
41 }
42 
43 int main() {
44     gets(s + 1);
45     n = strlen(s + 1);
46     s[0] = '0';
47 
48     l = 1, r = n - n / 2;
49     if (s[1] == '0') {
50         print();
51         return 0;
52     }
53 
54     for (i = 1 + (n & 1 ? 0 : 1), j = (n - i) / 2, r = n - j; i <= n / 3; i += 2, j --, r ++) {
55         l = j, k = s[1];
56         if (judge()) return 0;
57         l = i, k = s[l + 1];
58         if (judge()) return 0;
59     }
60 
61     p = 1, k = 49;
62     for (i = 1 + (n & 1 ? 1 : 0), j = (n - i) / 2, r = n - j - 1; i <= n / 3 - (n % 3 == 0); i += 2, j --, r ++) {
63         l = j;
64         if (judge()) return 0;
65         l = i;
66         if (judge()) return 0;
67     }
68 }
View Code

 

 

转载于:https://www.cnblogs.com/ytytzzz/p/8052867.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值