求 a/b 的小数表现形式。如果 a 可以整除 b 则不需要小数点。如果是有限小数,则可以直接输出。如果是无限循环小数,则需要把小数循环的部分用"()"括起来。
数据范围: ,
两个整数a和b,其中
0 <= a <= 1000 000
1 <= b <= 10 000
一个字符串,该分数的小数表现形式
10 1
10
10/1 = 10
1 2
0.5
1/2 = 0.5
1 3
0.(3)
1/3 = 0.333333...
1 6
0.1(6)
1/6 = 0.16666666....
1 7
0.(142857)
1 / 7 = 0.1428571428...
/* 小数点后部分,记录余数和商值, 余数再次出现,则对应的商值为循环开始,直到最终结束 若没有相同余数,则为有限小数。不考虑无限不循环小数 */ #include<bits/stdc++.h> using namespace std; #define N 1000 int main() { // freopen("input.txt", "r", stdin); int a, b, t; cin >> a >> b; cout << a / b; a = a % b; if(a == 0) return 0; cout << "."; map<int, int> m; vector<int> vec; t = 0; while(a != 0) { if(m.count(a) != 0) break; vec.push_back(a * 10 / b); m[a] = t++; a = a * 10 % b; } if(a == 0) { for(int i = 0; i < t; i++) cout << vec[i]; } else { int k = m[a]; for(int i = 0; i < k; i++) cout << vec[i]; cout << "("; for(int i = k; i < t; i++) cout << vec[i]; cout << ")"; } cout << endl; return 0; }
#include <iostream>
#include <unordered_map>
#include <vector>
using namespace std;
int main(){
int a,b;
cin>>a>>b;
int res=a/b;
cout<<res;
a=a%b;
if(a==0) return 0;
cout<<'.';
unordered_map map;
vector arr;
int i=0;
while(a!=0){
if(map.find(a)==map.end()){
arr.push_back(a*10/b);
map[a]=i;
i++;
a=a*10%b;
}
else{
int k=map[a];
for(int j=0;j<k;j++) cout<<arr[j];
cout<<'(';
for(int j=k;j<i;j++) cout<<arr[j];
cout<<')';
return 0;
}
}
for(int j=0;j<i;j++)
cout<<arr[j];
return 0;
}
#include<bits/stdc++.h> using namespace std; int main() { int a,b; while(cin>>a>>b) { cout<<(a/b); int t=a%b; if(t==0) return 0; cout<<"."; vector<int> ans; map<int,int> mp; int cnt=0; while(t) { if(mp.count(t)) break; mp[t]=cnt++; t=t*10; ans.push_back(t/b); t=t%b; } if(t==0) { for(int i=0;i<ans.size();i++) { cout<<ans[i]; } } else { for(int i=0;i<mp[t];i++) cout<<ans[i]; cout<<"("; for(int i=mp[t];i<ans.size();i++) cout<<ans[i]; cout<<")"; } cout<<endl; } return 0; }
using System; using System.Collections.Generic; using System.Linq; using System.Text.RegularExpressions; //总结目前牛客问题 第一,没有循环输入问题, 第二 有循环输入问题, 第三 输入有多余空格问题 ,第四 中间插入多余空行问题 .... namespace Test0001 { class Program { public static void Main(string[] args) { string line; while (!string.IsNullOrEmpty(line = Console.ReadLine())) Func(line); } public static void Func(string line) { var s1 = line.Split(' ').Select(x => int.Parse(x)).ToArray(); int num1 = s1[0], num2 = s1[1]; if (num1 % num2 == 0) { Console.WriteLine(num1 / num2); } else { int chu = num1 / num2; int yu = num1 % num2; int len = 0; Dictionary<int, int> dict = new Dictionary<int, int>(); string head = chu + ".", str = ""; while (yu != 0) { chu = yu * 10 / num2; yu = yu * 10 % num2; if (dict.ContainsKey(yu) && chu == str[dict[yu]] - '0') //并且首尾相等 { str = str.Insert(dict[yu], "(") + ")"; Console.WriteLine(head + str); return; } else if (!dict.ContainsKey(yu)) { dict.Add(yu, len); } str += chu; len++; } Console.WriteLine(head + str); } } } }
#include <bits/stdc++.h> using namespace std; int main(){ int a,b,t; cin>>a>>b; if(a%b==0) cout<<a/b<<endl; else{ cout<<a/b<<"."; a %= b; vector<int> v; map<int,int> m; int r = 0; while(a!=0){ if(m.find(a)!=m.end()) break; v.push_back(10*a/b); m[a] = r++; a = 10*a%b; } if(a==0) for(int i=0;i<r;i++) cout<<v[i]; else{ for(int i=0;i<m[a];i++) cout<<v[i]; cout<<"("; for(int i=m[a];i<r;i++) cout<<v[i]; cout<<")"; } cout<<endl; } return 0; }
a, b = map(int, input().split()) quoient, remainder = divmod(a, b) if remainder == 0: print(quoient) else: ans = [str(quoient), '.'] hash_map = {} a = remainder * 10 while remainder != 0: quoient, remainder = divmod(a, b) if (quoient, remainder) in hash_map: ans.insert(hash_map[(quoient, remainder)], '(') ans.append(')') break hash_map[(quoient, remainder)] = len(ans) ans.append(str(quoient)) a = remainder * 10 print(''.join(ans))
如果是整除直接输出 a / b 即可。
否则,模拟除法。保存每次的被除数以及它对应的商在小数字符串内的索引位置。如果能再次遇到此被除数,说明会产生循环从而不能除尽,那么此时就利用此数在map中存储的索引值来划分小数里的定长部分和循环部分。
如果a被除成0,说明能除尽,不需要加括号。
import java.util.*; public class Main { public static void main(String[] args) { Scanner sc = new Scanner(System.in); int a = sc.nextInt(); int b = sc.nextInt(); if(a % b == 0) { System.out.println(a / b); return; } Map<Integer, Integer> map = new HashMap<>(); StringBuilder res = new StringBuilder(); StringBuilder decimal = new StringBuilder(); res.append(a / b).append('.'); int index = 0; while(a != 0) { a = a % b * 10; if(map.containsKey(a)) { String str = decimal.toString(); String fixed = str.substring(0, map.get(a)); String loop = str.substring(map.get(a)); res.append(fixed).append('(').append(loop).append(')'); System.out.println(res.toString()); return; } decimal.append(a / b); map.put(a, index ++); } System.out.println(res.append(decimal).toString()); } }
#include <bits/stdc++.h>usingnamespacestd;intdecimal[10010] = {0};intmain() {inta, b;while(scanf("%d%d", &a, &b) != EOF) {intinteger = a / b;a %= b;if(a == 0) {printf("%d\n", integer);} else{intcnt = 0;intloop_pos = 0, loop_cnt = 0;map<int, int> num;while(a != 0) {a *= 10;decimal[cnt++] = a / b;if(num[a]) {loop_pos = num[a] - 1;loop_cnt = cnt - num[a];break;} else{num[a] = cnt;}a %= b;}printf("%d.", integer);if(a == 0) {for(inti = 0; i < cnt; i++) {printf("%d", decimal[i]);}printf("\n");} else{for(inti = 0; i < loop_pos; i++) {printf("%d", decimal[i]);}printf("(");for(inti = 0; i < loop_cnt; i++) {printf("%d", decimal[loop_pos++]);}printf(")\n");}}}return0;}
import java.util.*; /* 关键是如果是无限循环小数怎么确定循环节:如果曾经出现过的被除数再次出现, 那么上一次出现的位置就是循环节的开头,此处就是循环节的结尾(不包括),举个栗子 11/7=1……4,整数部分是1,然后计算小数部分 被除数 商 余数 40 5 5 50 7 1 10 1 3 30 4 2 20 2 6 60 8 4 40 5 5 此处被除数40再次出现,那么循环节就是(571428) */ public class Main { public static void main(String[] args) { Scanner scanner = new Scanner(System.in); int a = scanner.nextInt(); int b = scanner.nextInt(); StringBuilder result = new StringBuilder(); // 先求出整数部分 result.append(a / b); // 如果有小数部分再求小数部分 if (a % b != 0) { a = a % b; result.append('.'); // 使用hashmap记录每一个被除数和它上一次出现的位置 HashMap<Integer, Integer> map = new HashMap<>(); while (a != 0) { a *= 10; // 新的被除数 if (map.get(a) != null) { // 如果这个被除数曾经出现过,那么找到了循环节,游戏结束 // 在上一次此被除数出现的位置之前插入'(' result.insert(map.get(a), "("); // 在最后插入')' result.append(')'); break; } // 没有出现过就将此被除数插入map map.put(a, result.length()); // 求出商和余数 result.append(a / b); a = a % b; } } // 输出结果 System.out.println(result); } }
#include<bits/stdc++.h> using namespace std; typedef long long ll; map<int, int> ma; string solve(int x, int y) { int zhengshu = x / y; string string_zs = to_string((ll) zhengshu); string xiaoshu = ""; while(x % y != 0) { x = (x % y) * 10; int shang = x / y; if(ma.count(x) != 0) {//若此时的x出现过 说明已经循环了 xiaoshu.insert(ma[x], "(");//在循环的位置插入括号 xiaoshu.push_back(')'); break; } else { xiaoshu.push_back(shang + '0'); ma[x] = xiaoshu.size() - 1;//保存循环点的位置 } } if(!xiaoshu.empty()) return string_zs + "." + xiaoshu; else return string_zs; } int main() { int x, y; while(cin>>x>>y){ ma.clear(); cout<<solve(x, y)<<endl; } } /* 1 2 1 3 1 6 1 7 */
# 精华答案的Python版 def compute(): a,b = list(map(int,input().split())) mod = a % b quo1 = a // b # 如果整除 if not mod: return quo1 modList = [] # 如果非整除 while mod: # 将余数储存在列表 modList.append(mod) mod = mod*10 % b # 如果余数出现两次 if mod in modList: # 循环开始的位置为i loopStartIdx = modList.index(mod) # format result quo2 = str(quo1) + '.' for i in range(loopStartIdx): quo2 += str(modList[i]*10//b) quo2 += '(' for i in range(loopStartIdx,len(modList)): quo2 += str(modList[i]*10//b) return quo2 + ')' print(compute())
// 方法很常规 寻求更好解法 #include<iostream> #include<vector> #include<string> #include<sstream> #include<unordered_map> using namespace std; class Solution{ public: string converIntTOS(int n) { string str; stringstream s; s << n; s >> str; return str; } string conver(int n,int m){ int znum; vector<int> xnum; if(n % m == 0){//可以整除 return converIntTOS(n/m); } if(n > m){//计算整数 znum = n/m; } else{ znum = 0; } xnum.push_back(-1); int temp = n % m; int k = -1; unordered_map<int,int> hash;//余数 + 第几个 int hashNum = 1; hash[temp] = hashNum; while(temp > 0){ int s = (temp*10) / m; int y = (temp*10) % m; if(y == 0){ xnum.push_back(s); break; } else{ k = -1; if(hash[y] != 0){//发生了循环 xnum.push_back(s); k = hash[y]; break; } else{//没找到继续 hash[y] = ++hashNum; xnum.push_back(s); temp = y; } } } string res = ""; res += converIntTOS(znum); res += "."; if(k == -1){//不是循环 for(int i=1;i<xnum.size();i++){ res +=converIntTOS(xnum[i]); } } else{// 是循环 for(int i=1;i<k;i++){ res += converIntTOS(xnum[i]); } res += "("; for(int i=k;i<xnum.size();i++){ res += converIntTOS(xnum[i]); } res +=")"; } return res; } }; int main(){ int n,m; cin>>n>>m; Solution c1; cout<<c1.conver(n,m)<<endl; return 0; }
import java.util.HashMap; import java.util.Scanner; public class aDividedb { public static void main(String[] args) { Scanner sc = new Scanner(System.in); String[] strs = sc.nextLine().split(" "); int a = Integer.parseInt(strs[0]); int b = Integer.parseInt(strs[1]); if (a % b == 0) { System.out.println(a / b); return; } StringBuilder sb = new StringBuilder(); sb.append(a / b).append("."); a = (a - (a / b) * b) * 10; int offset = sb.length(); HashMap<Integer, Integer> marked = new HashMap<>(); marked.put(a, offset); while (true) { int r = a % b; if (r == 0) { break; } int c = a / b; sb.append(c); a = (a - (a / b) * b) * 10; if (marked.containsKey(a)) { sb.insert(marked.get(a), "("); sb.append(")"); break; } else { marked.put(a,sb.length()); } } System.out.println(sb.toString()); } }
def solve(x,y): k=x//y; pre,back=str(k),""; cycle={} while x%y: x=(x%y)*10; if cycle.get(x)!=None: i=cycle[x] back=back[:i]+"("+back[i:]+")"; break; else: p=x//y; back+=str(p); cycle[x]=len(back)-1; if back: return pre+"."+back; else: return pre x,y=list(map(int,input().split())) print(solve(x,y))
import sys a, b = map(int, sys.stdin.readline().strip().split()) if a % b == 0: print(a // b) else: L1 = [] L2 = [] flag = False while a % b != 0: L1.append(str(a//b)) yushu = a%b if yushu in L2: index = L2.index(yushu) flag = True print(str(L1[0])+'.'+''.join(L1[1:index+1])+'('+''.join(L1[index+1:])+')') break else: L2.append(yushu) a = yushu*10 if flag == False: L1.append(str(a//b)) print(str(L1[0])+'.'+''.join(L1[1:]))
#include<stdio.h> int main() { int a,b; scanf("%d%d",&a,&b); int num = a/b; printf("%d",num); if(a%b==0) { printf("\n"); return 0; } printf("."); int t = a%b; int set[50000]={0}; int num2[100000]; //从下标1开始 int flag=0;//1是有限小数 0 是无限小数 int i=1; while(t!=0&&flag==0) { if(set[t]!=0) { flag=set[t];//循环开始的位置 } set[t]=i; t=t*10; num2[i++] =t/b; t= t%b; } if(flag==0) { for(int j=1;j<i;j++) printf("%d",num2[j]); printf("\n"); } else { if(flag>1) for(int j=1;j<flag;j++) printf("%d",num2[j]); printf("("); for(int j=flag;j<i-1;j++) printf("%d",num2[j]); printf(")\n"); //printf("%d\n",i); } } //综上所有的分数都是有理数,终于明白了
import java.util.HashMap; import java.util.Map; import java.util.Scanner; //38 public class Main { //整除直接输出,否则模拟运算,借助map储存位置并判断重复 public static void main(String[] args) { Scanner sc = new Scanner(System.in); int a = sc.nextInt(); int b = sc.nextInt(); String res = a*1.0/b+""; if(a/b==a*1.0/b){ //整除直接输出 System.out.println(a/b); return; } String[] s = res.split("\\."); StringBuilder sb = new StringBuilder(); String re = a/b+"."; //小数点前 Map<Integer, Integer> map = new HashMap<>(); int k = 0; a = a%b; while(a>0){ if(map.containsKey(a*10)){ sb.insert(map.get(a*10), "(").append(")"); break; }else{ map.put(a*10,k++ ); sb.append(a*10/b); a = ((a*10)%b); } } re +=sb.toString(); System.out.println(re); } }
a, b = map(int, input().split()) int_num = a // b left = a % b ans_num = [] index_num = {} i = 0 while left != 0 and left not in index_num: index_num[left] = i res_part = left * 10 // b ans_num.append(res_part) left = left * 10 % b i += 1 if len(ans_num) == 0: print(int_num) elif left == 0: print(str(int_num)+".", end="") for mod_num in ans_num: print(str(mod_num), end="") print() else: print(str(int_num)+ ".", end="") for j in range(index_num[left]): print(str(ans_num[j]), end="") print("(", end="") k = index_num[left] for num in ans_num[k:]: print(str(num), end="") print(")")