[CodeForces 490C]Hacking Cypher[math]

来源:互联网 发布:银行数据录入员不靠谱 编辑:程序博客网 时间:2024/05/21 09:44
题目链接:[CodeForces 490C]Hacking Cypher[math]

题意分析:

将一个长度<=1e6的数字切成两半,使得左半边能被a整除,后半边能被b整除,输出任意一种满足条件的切法,不能有前导零。(a,b<=1e8)

解题思路:

设当前数为num,考虑从左往右,每新增一个数字cur,当前数为num = num * 10 + cur。每一次取模即可判断是否能被a整除,同理,从右往左,每一次新的数就是num = 10^x * cur + num。然后标记下可行位置,最后判断一遍即可。

个人感受:

从小处往大处慢慢考虑,这种思想还是不能熟练使用啊。之前老想着除数和被除数的关系,一直不能解。

具体代码如下:

#include<iostream>#include<string>#define ll long longusing namespace std;const int MAXN = 1e6 + 111;bool ok[2][MAXN];int main(){    string digit;    ll a, b, num = 0;    cin >> digit >> a >> b;    for (int i = 0; i < digit.length(); ++i) {        ll cur = digit[i] - '0';        num = (((num % a) * (10 % a)) % a + cur % a) % a;        if (!num) ok[0][i] = 1;    }    num = 0;    int base = 1;    for (int i = digit.length() - 1; i >= 0; --i) {        ll cur = digit[i] - '0';        num = (((cur % b) * (base % b)) %b + num % b) % b;        if (!num && cur) ok[1][i] = 1;        base = (base * 10) % b;    }    for (int i = 1; i < digit.length(); ++i) {        if (ok[0][i - 1] && ok[1][i]) {            cout << "YES\n";            for (int j = 0; j <= i - 1; ++j) cout << digit[j];            cout << '\n';            for (int j = i; j < digit.length(); ++j) cout << digit[j];            cout << '\n';            return 0;        }    }    cout << "NO\n";    return 0;}


0 0