程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> Codeforces Round #279 (Div. 2)

Codeforces Round #279 (Div. 2)

編輯:C++入門知識

Codeforces Round #279 (Div. 2)


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;
}














  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved