Codeforces Round #449 (Div. 2) 897B. Chtholly's request

来源:互联网 发布:水表读卡器软件 编辑:程序博客网 时间:2024/06/05 05:34

题意:位数为偶数且为回文的正整数成为zcy数字,求前k个zcy数字的和对p取余

思路:先打印出前一百位找规律

        我的规律:发现下一个zcy数是上一个zcy数从最中间的两个数往两边变化,如果不为‘9’那么就让这个数字加‘1’对称的那个数字也加一然后跳出,为‘9’就变为‘0’继续找,如果都最外层还是九那就需要在子串的两端各加一个‘1’。(感觉我这个想法有点蠢)

        后来听了一个朋友的想法:第i个zcy数就是i和反序i的连接在一起,例如:第1个zcy数字位11,第2个为22,第10个zcy数就是1001,第123个zcy数位123321等等

所以我们模拟得到前N个zcy数字串转化为数字加起来然后对p取余就OK了。注意要用long long


#include<bits/stdc++.h>using namespace std;const int MAXN = 1e5 + 5;int k,p;long long a[MAXN];long long get(int num)//得到 “num+反num”的数字 {//数字转字符串 string s = "";stringstream ss;ss << num;ss >> s;string rs = s;reverse(rs.begin(),rs.end());//字符串反转 s = s + rs;//连接正反字符串 //字符串转数字 long long a;ss.clear();ss << s;ss >> a;return a;} void init(){a[0] = 0;for(int i = 1; i < MAXN; i++) //得到前MAXN个数字并做前缀和 {a[i] = get(i);a[i] += a[i - 1];}}int main(){init();while(~scanf("%d%d",&k,&p)){printf("%d\n",a[k] % p);}return 0;}



#include<bits/stdc++.h>using namespace std;const int MAXN = 1e5 + 5;long long a[MAXN];string GZ(string s)//构造字符串 {int len = s.length();int i = len/2 - 1,j = len / 2;//两个指针同时往前后两边扫,互相对称 while(1){if(i >= 0){if(s[i] != '9')//不为9{s[i] = s[i] + 1;s[j] = s[j] + 1;break;}else{s[i] = '0';s[j] = '0';}}else{s.insert(s.begin(),'1');s.insert(s.end(),'1');break;}i--;j++; } return s;}void init(){string s = "11";for(int i = 1; i < MAXN; i++)//构造字符串 {s = GZ(s);//字符串变数字 stringstream ss;ss << s;ss >> a[i];} a[0] = 11;for(int i = 1; i < MAXN; i++) a[i] = a[i] + a[i - 1];//前缀和 }int main(){init();int k, p;while(~scanf("%d%d",&k,&p)){printf("%d\n",a[k - 1] % p);}return 0;}/*2 1005 30*/




阅读全文
0 0
原创粉丝点击