Codeforces Round #279 (Div. 2)

2015-01-27 06:03:56 · 作者: · 浏览: 9
C. Hacking Cypher time limit per test 1 second memory limit per test 256 megabytes input standard input output standard output

Polycarpus participates in a competition for hacking into a new secure messenger. He's almost won.

Having carefully studied the interaction protocol, Polycarpus came to the conclusion that the secret key can be obtained if he properly cuts the public key of the application into two parts. The public key is a long integer which may consist of even a million digits!

Polycarpus needs to find such a way to cut the public key into two nonempty parts, that the first (left) part is divisible by a as a separate number, and the second (right) part is divisible by b as a separate number. Both parts should be positive integers that have no leading zeros. Polycarpus knows values a and b.

Help Polycarpus and find any suitable method to cut the public key.

Input

The first line of the input contains the public key of the messenger ― an integer without leading zeroes, its length is in range from 1 to106 digits. The second line contains a pair of space-separated positive integers a, b (1?≤?a,?b?≤?108).

Output

In the first line print "YES" (without the quotes), if the method satisfying conditions above exists. In this case, next print two lines ― the left and right parts after the cut. These two parts, being concatenated, must be exactly identical to the public key. The left part must be divisible by a, and the right part must be divisible by b. The two parts must be positive integers having no leading zeros. If there are several answers, print any of them.

If there is no answer, print in a single line "NO" (without the quotes).

Sample test(s) input
116401024
97 1024
output
YES
11640
1024
input
284254589153928171911281811000
1009 1000
output
YES
2842545891539
28171911281811000
input
120
12 1
output
NO
 
 
题意:给你一个串,问是否能把它分成两段,前面一段能整除a,后面一段能整除b,并且后一段不能有前导0
 
 
思路:这题就是大数取模的运用,弄明白大数取模的原理后我们可以分别先从前往后扫,标记那些可以整除a的位置,然后再从后往前扫,看是否有能整除b的,判断前面i-1个是否整除a就行,至于为什么从后往前扫,是因为这样可以减少时间复杂度,如果两次都是从前往后第二次最坏会o(n^2)
如果不懂大数取模看下面:
a+b)%n=(a%n+b%n)%n

(a-b)%n=(a%n-b%n+n)%n

为什么要加n,由于a%n可能小于b%n,所以加n保证为正整数

a*b%n=(a%n*b%n)%n

这些事大整数取模的基础

int mod(char str[],int num)
{
    int number[100];
    for(int i=0;i
   
#include 
   
    
#include 
    
      #include 
     
       #include 
      
        #include 
       
         using namespace std; const int maxn = 1e6+10; char str[maxn]; bool flag[maxn]; int a,b; int main() { #ifdef xxz freopen("in.txt","r",stdin); #endif while(scanf("%s%d%d",str,&a,&b) != EOF) { int len = strlen(str); int sum = 0; memset(flag,0,sizeof(flag)); for(int i = 0; i < len; i++) { sum = (sum*10 + (str[i] - '0'))%a; if(i < len-1 && sum == 0 && str[i+1] != '0') flag[i] = true; } bool ok = false; int pos = 0, k = 1; sum = 0; for(int i = len-1; i > 0; i--) { sum = (sum + (str[i] - '0')*k)%b; k *= 10; k %= b; if(sum == 0 && flag[i-1]) { ok = 1; pos = i; break; } } if(ok) { printf("YES\n"); for(int i = 0; i < pos-1; i++) printf("%c",str[i]); printf("%c\n",str[pos-1]); for(int i = pos; i < len-1; i++) printf("%c",str[i]); printf("%c\n",str[len-1]); } else printf("NO\n"); } return 0; }