codeforces 490C Hacking Cypher(大数逆向取模)

题意:

给定一个长度为10^6的数n,问能不能把这个数分成两半,使它的前一半组成的数被整数a整除,后一半组成的数被整数b整除,a,b小于10^8,且要求分成的数不能有前导0.


题解:

字符串a记录大数n.

大数取模的板子改进一下即可,用一个xzero[i]数组记录a[0]到a[i]组成的数对a取模是否为0.

然后将大数取模逆过来写一遍,用一个yzero[i]数组记录a[len-1]到a[i]组成的数对b取模是否为0.

最后从0到len-1跑一遍xzero和yzero数组,如果有一个位置i满足xzero[i]=1以及yzrero[i+1]=1,那么这个位置分割下来的数就符合,输出即可。


这个题一开始只正向取模去做了一次,然后跑循环对后面部分在跑一次正向取模,超时了 。然后想到能不能逆向取模跑一下,但是考虑到幂每次乘10太大了,不敢写。结束后队友过了,用的就是我想的思路,我才想到可以每次都对幂取模啊。唉,理解还是不到位吧,每次都差一点。取模的式子当中的每一项可以先单独取模一下(不包括分母),这点还是没能活学活用。


代码:

#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
const int maxn=1e6+5;
char a[maxn];
bool xzero[maxn];
bool yzero[maxn];
int main()
{
    scanf("%s", a);
    int x, y;
    scanf("%d%d", &x, &y);
    int mod=0;
    int i, j;
    int len=strlen(a);
    for(i=0; i<len-1; i++) // 正向取模
    {
        mod=(mod*10+a[i]-'0')%x;
        if(mod==0 && a[i+1]!='0')xzero[i]=1;
    }
    int ten=1;
    mod=0;
    for(i=len-1; i>0; i--) // 逆向取模
    {
        ten%=y;
        if(a[i]=='0')
        {
            ten*=10;
            ten%=y;
            continue;
        }
        mod=(mod+ten*(a[i]-'0'))%y;
        if(mod==0)yzero[i]=1;
        ten*=10;
    }
    for(i=0; i<len-1; i++)
    {
        if(xzero[i]&&yzero[i+1])
        {
               printf("YES\n");
               for(j=0; j<=i; j++)printf("%c", a[j]);
               printf("\n");
               for(; a[j]; j++)printf("%c", a[j]);
               printf("\n");
               break;
        }
    }
    if(i>=len-1)printf("NO\n");

    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值