[CodeForces 490C]Hacking Cypher[math]

题目链接: [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 long
using 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;
}


你可能感兴趣的:(Math,字符串)