1. 程式人生 > >hihocoder1311 二進制小數

hihocoder1311 二進制小數

cout 描述 col 模版 pre ret name code logs

  

時間限制:10000ms
單點時限:1000ms
內存限制:256MB
描述
給定一個十進制小數X,判斷X的二進制表示是否是有限確定的。

例如0.5的二進制表示是0.1,0.75的二進制表示是0.11,0.3沒有確定有限的二進制表示。

輸入
第一行包含一個整數 T (1 ≤ T ≤ 10),表示測試數據的組數。

以下T行每行包含一個十進制小數 X (0 < X < 1)。 X一定是以"0."開頭,小數部分不超過100位。

輸出
對於每組輸入,輸出 X 的二進制表示或者NO(如果 X 沒有確定有限的二進制表示)。

樣例輸入
3
0.5
0.75
0.3
樣例輸出
0.1
0.11
NO

題意:十進制小數轉二進制,輸出二進制小數,無限循環則輸出NO

題解:二進制小數,高精度乘法加個特判即可,這裏還用到了hash

#include <bits/stdc++.h>
using namespace std;
map<int, int>mp;
string s, ans;
int BKDRHash(string s){
    long long seed=131;
    long long hash=0;
    int i = 0;
    while(i<s.size()&&s[i]) hash=hash*seed+(s[i++]);
    return (hash & 0x7FFFFFFF
); } string Multiply(string s,int x){//模版 reverse(s.begin(),s.end()); int cmp=0; for(int i=0;i<s.size();i++){ cmp=(s[i]-0)*x+cmp; s[i]=(cmp%10+0); cmp/=10; } while(cmp){ s+=(cmp%10+0); cmp/=10; } reverse(s.begin(),s.end());
return s; } bool f(string s){ int i; for(i=0;i<s.size();i++) if(s[i] != 0) break; if(i>=s.size()) return 1; return 0; } int main(){ int T, flag, l; cin>>T; while(T--){ cin>>s; int i = s.size()-1; while(i>=0&&s[i]==0) i--; if(i>=0&&s[i]!=5) { cout<<"NO"<<endl; continue; } ans = "";mp.clear(); flag = 0; s.erase(0,2); l = s.size(); while(mp[BKDRHash(s)] == 0){ mp[BKDRHash(s)] = 1; s = Multiply(s, 2); if(f(s)){ flag = 1; break; } if(s.size() != l) s.erase(0, 1), ans += 1; else ans += 0; } if(flag == 1) cout<<"0."<<ans<<endl; else cout<<"NO"<<endl; } return 0; }

hihocoder1311 二進制小數