#include <iostream> #include <string> using namespace std; const int MOD = 20123; void removeprezeros(string& s) { while (!s.empty() && s[0] == '0') { s.erase(s.begin()); } if (s.empty()) { s = "0"; } } int smod(string& s) { int rest = 0; for (int i = 0; i < s.length(); i++) { int v = rest * 10 + (s[i] - '0'); rest = v % MOD; } return rest; } void sincr(const string& s, string& ans) { int carry = 1; string temp = ""; for (int i = s.length() - 1; i >= 0; i--) { int v = s[i] - '0' + carry; temp.insert(temp.begin(), (char)((v % 10) + '0')); carry = v / 10; } if (carry > 0) { temp.insert(temp.begin(), (char)(carry + '0')); } ans.clear(); ans = move(temp); } int funkmod(int k, int* tenmods) { if (k == 1) { return 2 % MOD; } else if (k <= 0) { return 0 % MOD; } else { return ( (((2 % MOD) * tenmods[k - 1]) % MOD) + (((10 % MOD) * (funkmod(k - 1, tenmods))) % MOD) ) % MOD; } } int fun(const string& s, int* funks, int* tens) { if (s.length() <= 0) { return 0; } else if (s.length() == 1) { int v = s[0] - '0'; return v == 0 ? 0 : v == 1 ? 1 : 2; } else { int k = s.length(); int ans = 0; int fv = s[0] - '0'; for (int i = 0; i < fv; i++) { ans += funks[k - 1]; ans %= MOD; if (i == 1 || i == 2) { ans += tens[k - 1]; ans %= MOD; } } string temp = s.substr(1, k - 1); if (fv == 1 || fv == 2) { string incred; sincr(temp, incred); ans += smod(incred); ans %= MOD; } ans += fun(temp, funks, tens); ans %= MOD; return ans; } } int main() { int tenmods[103] = {0}; int t = 1; for (int i = 0; i <= 102; i++) { tenmods[i] = t; tenmods[i] %= MOD; t *= 10; t %= MOD; } int funks[103] = {0}; for (int i = 1; i <= 102; i++) { funks[i] = funkmod(i, tenmods); } char cline[500] = {0}; while (scanf("%s", &cline) == 1) { string line = cline; removeprezeros(line); printf("%d\n", fun(line, funks, tenmods)); } }
/** 比如输入12345,那么先算F(1),再由F(1)算出F(12),依次再算出F(123),F(1234),F(12345); 主要计算的就是res=(res-cnt)*10+cnt*(t+1)+num*2+min(t,2); res代表循环到此位的结果;num是实际输入的数;cnt是num这个数中1,2的数量; 例如F(12)=res,需要算F(123) 1.显然12变成了12X的形式,所以原来1-11中每一个数都可以加上一个个位(因为不知道个位是不是9,所以最后一个12不能乘10,以后单独计算), 而个位是从0-9,所以原来的每个数都有10中变化,而最后一个数12的1,2的数量为cnt,所以有(res-cnt)*10,; 2.上一步中余有一个12没有计算,显然12X这个数的个位只能是0-3,所以有cnt*(t+1); 3.上面的计算中都没有考虑对个位为1,2的计数,个位为1,2的显然是每10个数中有2个,所以有num*2(例如12中0-11都可以个位是1,2) 4.12X个位的1,2个数,直接判断就行,min(t,2); */ import java.util.*; public class Main{ private static int Mod = 20123; public static void main(String[] args){ Scanner in = new Scanner(System.in); while(in.hasNext()){ char[] chs = in.nextLine().toCharArray(); int len = chs.length; int res = 0; int num = 0; int cnt = 0; for(int i = 0; i < len; i++){ int curNum = chs[i] - '0'; res = (res - cnt) * 10 + cnt * (curNum + 1) + num * 2 + Math.min(curNum, 2); if(curNum == 1 || curNum == 2) cnt++; num = (num * 10 + curNum) % Mod; res = res % Mod; } System.out.println(res); } } }
#include<iostream> #include<string> using namespace std; string s; int Pow(int n) { int d = 10,res = 1; while(n) { if(n & 1) { res = (d * res) % 20123; } d = (d * d) % 20123; n >>= 1; } return res; } int GetNum(int i,int j) { int d = 0; for(i;i <= j;i++) { d = 10 * d + s[i] - '0'; d %= 20123; } return d; } int main() { while(cin >> s) { int sum = 0; for(int i = 0;i < s.size();i++) { int a = GetNum(0,i - 1); int b = GetNum(i + 1,s.size() - 1); int p = Pow(s.size() - i - 1); if(s[i] > '2') { sum += ((a + 1) * 2 * p) % 20123; } else if(s[i] == '2') { sum += ((a * 2 + 1) * p + b + 1) % 20123; } else if(s[i] == '1') { sum += (((a * 2) * p + b + 1)) % 20123; } else if(s[i] == '0') { sum += ((a * 2) * p) % 20123; } sum %= 20123; } cout << sum << endl; } return 0; }
#include <bits/stdc++.h> using namespace std; int main() { string input; while(cin>>input) { int n=input.length(); string s=input; reverse(input.begin(),input.end()); int x=0,p=1,k=20123,res=0,m=0; for(int i=0;i<n;++i) { int last=input[i]-'0'; int smallpart=(last*x%k+(last>1?p:0)+(last>2?p:0))%k; int equalpart=((last==1||last==2?(m+1)%k:0)+res)%k; res=(smallpart+equalpart)%k; x=(2*p%k+10*x%k)%k; m=((last*p)%k+m)%k; p=p*10%k; } cout<<res<<endl; } return 0; }
def counti(N, i): count=0; base=10; tmp=N while(tmp): count += N//base*base//10 if(N%base >= (i*base//10)): if(N%base < ((i+1)*base//10)): count += (N%(base//10) + 1); else: count += base//10 base *= 10 tmp //= 10 return count while True: try: N = int(input()) result = (counti(N,1)+counti(N,2))%20123 print(result) except: break
#include<stdio.h> #include<string.h> char str[102]; int Pow10(int n){ int ret = 1; int i = n; while(i--){ ret *= 10; ret %= 20123; } return ret; } int Get(int a, int b){ int i = b; int ret = 0; while(i != a-1){ ret += (str[i]-'0')*Pow10(b-i); ret %= 20123; i--; } return ret; } int main(){ while(scanf("%s", str) == 1){ int len = strlen(str); int i; int sum = 0; for(i = 0; i < len; i++){ int n = len-i-1; if(str[i] > '2'){ sum += 2*Pow10(n) *(Get(0, i-1) + 1); }else if(str[i] == '2'){ sum += 2*Pow10(n) * Get(0, i-1) + Pow10(n) + Get(i+1, len-1) + 1; }else if(str[i] == '1'){ sum += 2*Pow10(n) * Get(0, i-1) + Get(i+1, len-1) + 1; }else{ sum += 2*Pow10(n) * Get(0, i-1); } sum %= 20123; } printf("%d\n", sum); /***********check**********/ /* int num; sum = 0; sscanf(str, "%d", &num); for(i = 1; i <= num; i++){ char temp[11]; sprintf(temp, "%d", i); int j; for(j = 0; j < strlen(temp); j++){ if(temp[j] == '1' || temp[j] == '2') sum++; if(sum == 20123) sum = 0; } } printf("%d\n", sum); */ } return 0; }这题和暴力解法能对上,但是和答案对不上啊,觉得答案可能有点问题。