求 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(")")