題目
題意略。
分析:這題我把式子各種展開,然後推了一個東西出來,枚舉位元,然後求得一個x,若x能表示為當前總位元減一的base下的數,則當前位元為最小。這樣寫了後TLE了,判斷那裡可能耗時了。
看了別人的題解後,發現我考慮複雜了。其實這就是一個base位進位下的多位元乘以一位元的乘法運算。寫成豎式如下,
a0a1a2...an-1c
× f
----------------------
ca0a1a2...an-1
(a0a1a2...an-1c 表示 factor1,f表示factor2,c為需要移動的數字)。
運算過程如,c*f 為最低位元運算後的結果 c*f 在base下表示為 c*f/base、(c*f)%base 兩位元,其中c*f/base為進位,c*f%base為結果的當前位,由題目條件知,an-1 = c*f%base.
所以我們繼續進行an-1*f,直到結果的當前位等於c,且進位為0。可見這就是小學時給的那種豎式留幾個空叫你填空的那種題目,只不過由十進位改成了base進位。
代碼:
#include <iostream>#include <cmath>#include <string>using namespace std;int main() {int base, n, m;while(cin >> base >> n >> m) {if(m == 1) {cout << 1 << endl;continue;}int carry = 0, cur = n, i = 1;for(; ; i++) {int tmp = cur * m + carry;carry = tmp / base; //滿base進一cur = tmp % base; //當前位if(carry == 0 && cur == n) {cout << i << endl;break;}}}return 0;}
TLE的代碼:
#include<iostream>using namespace std;int b, c, f;int is(int x, int n) //x能否表示成b下的n位元{ int cnt=0; for(; x; x/=b, cnt++); if(cnt == n) return 1; else return 0;}int main(){ while(cin>>b>>c>>f) { int i; //first factor的位元 n int b_pow = 1; //b的n-1次 for(i=1; b_pow<=f; i++) b_pow*=b; //①n能不能為1?②<=,x不能為0? for(; ; i++, b_pow*=b) { int t1 = c*(b_pow-f); int t2 = (f*b-1); if(t1%t2 != 0) continue; //x為整數 int x = t1/t2; if(is(x, i-1)) { cout<<i<<endl; break; } } }}