codeforces 490C. Hacking Cypher 解题报告

题目链接:http://codeforces.com/problemset/problem/490/C

题目意思:给出一个可能有10^6 位长的字符串且没有前导0的整数,问能否一分为二,使得前面的一部分被 a 整除 且 后面那部分被 b 整除,可以的话输出 “YES” 和 划分后的两部分,否则输出“NO”.

  看到字符串这么长,一下子就吓怕了~~~用 mod 即可!这些要靠数学积累吧......

  好常规的方法做——暴力枚举,当然不能遗漏啦,所以从左至右直到倒数第二个数字,都要算出mod a 的结果且保存到 vis[] 数组里面(vis初始化为-1)。然后从右往前直到顺数第二个数字,算出 mod b 的结果,当这个结果为0(即可以被b整除),且vis[前一位数字] = 0(表示前面的数可以被a整除),还有一个容易遗漏的一点,就是没有前导0(对应代码中的 s[i] != '0')那么就代表找到一个解。遍历完之后都没有的话就表示没有答案,输出“NO”

   

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstdlib>
 4 #include <cstring>
 5 using namespace std;
 6 
 7 const int maxn = 1e6 + 5;
 8 int vis[maxn];     // 保存string中 0~len-1 个数字mod a 的结果
 9 string s;
10 
11 int main()
12 {
13     #ifndef ONLINE_JUDGE
14         freopen("in.txt", "r", stdin);
15     #endif // ONLINE_JUDGE
16     int a, b;
17     while (cin >> s >> a >> b)
18     {
19         memset(vis, -1, sizeof(vis));
20         int tmp = 0;
21         int len = s.size();
22        
23         for (int i = 0; i < len-1; i++)    // 至少要留一位给 b 嘛
24         {
25             tmp = (tmp * 10 + (s[i]-'0')) % a;     // 用到数学一些小知识
26             vis[i] = tmp;
27         }
28 
29         int base = 1;
30         tmp = 0;
31         for (int i = len-1; i > 0; i--)      // 同理,a都要至少留一位数
32         {
33             tmp = ((s[i]-'0') * base + tmp) % b;
34             base = base * 10 % b;
35             if (tmp == 0 && !vis[i-1] && s[i] != '0')
36             {
37                 cout << "YES" << endl;
38                 cout << s.substr(0, i) << endl;
39                 cout << s.substr(i, len-i) << endl;
40                 return 0;
41             }
42         }
43         cout << "NO" << endl;
44     }
45     return 0;
46 }
View Code

 

posted @ 2014-11-29 09:56  windysai  阅读(368)  评论(0编辑  收藏  举报