【數學推導】數字變換

題目描述

Alice 給了 Bob 一個數 k,求有多少個數 x,知足:從 x 的某個數位(不能是最後一位)後加一個乘號,運算獲得一個數 y,使得 xy=k。html

好比:若是 k=123,那麼 277 就是一個符合要求的數,由於 2772×77=123。c++

Bob 以爲這個問題太難了,但願你能夠幫他解決。ide

輸入輸出格式

輸入格式:spa

一行一個整數 k,意義如上所述。code

輸出格式:htm

一行一個整數,表示答案。blog

輸入輸出樣例

輸入樣例#1: 
123
輸出樣例#1: 
3
輸入樣例#2:
2333
輸出樣例#2: 
9
輸入樣例#3: 
999999999
輸出樣例#3:
34

【題解】:
這個題目也是經過講評後我才知道這個怎麼作的。
首先讀一遍題目:
題目須要咱們找出全部符合一種 形式的數 以一種形式等於k。
形式的數是指:X = a*(10^t) + b
而後一種形式爲: X - a * b = k

根據這個題目咱們知道 K 的範圍爲: 1e9
咱們能夠枚舉 10^t,t = 1,2,3……9.
咱們設:t = 10^t。

而後有:a*t-a*b=k
因式分解:(a-1)*(t-b)=k-t
而後經過這個式子進行分析。
一、當k-t<0,不存在a,b,由於左邊都是整數。
二、當k-t>0,能夠經過根號n枚舉全部k-t的因數,而後排序找出對應的a,b。
三、當k-t==0,因爲t>b,∴a=1,而後b能夠b<t的任意數。
注意去重:
好比100000,可能在討論(2)時涉及了,而後計算(3)時重複了。
貼上代碼:
 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 typedef long long ll;
 4 ll k,ans,A,B,K,a,b,F;
 5 set<ll>Ans;
 6 vector<ll> V;
 7 int main()
 8 {
 9     scanf("%lld",&k);
10     for(ll t=10 ; t<=INT_MAX ; t*=10 ){
11         if( k-t > 0 ){
12             K = k-t;
13             //printf("%lld %lld \n",t,K);
14             for(ll i=1 ; i*i<=K ; i++ ) {
15                 V.push_back( i );
16                 if( i*i != K ){
17                     V.push_back( K/i );
18                 }
19             }
20             sort(V.begin(),V.end() );
21             V.erase( unique( V.begin(),V.end() ), V.end() );
22             for(auto A:V){
23                 a = A + 1 ;
24                 b = t - K/A;
25                 if( b<t && b>=0 && a*t + b - a*b == k){
26                     //cout << a*t + b << endl ;
27                     Ans.insert( a*t + b );
28                 }
29             }
30         }else if ( k-t == 0 ){
31             F = t ;
32         }
33     }
34     if( F ){
35         //printf("###\n");
36         set<ll> ::iterator it1 = lower_bound(Ans.begin(),Ans.end(),F);
37         set<ll> ::iterator it2 = lower_bound(Ans.begin(),Ans.end(),2*F);
38         //it2--;
39         Ans.erase(it1,it2);
40     }
41     ans = Ans.size() + F;
42     printf("%lld\n",ans);
43     return 0 ;
44 }
數字變換
相關文章
相關標籤/搜索