[编程题]a/b
  • 热度指数:4593 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 32M,其他语言64M
  • 算法知识视频讲解
求 a/b 的小数表现形式。如果 a 可以整除 b 则不需要小数点。如果是有限小数,则可以直接输出。如果是无限循环小数,则需要把小数循环的部分用"()"括起来。

数据范围:

输入描述:
两个整数a和b,其中

0 <= a <= 1000 000

1 <= b <= 10 000


输出描述:
一个字符串,该分数的小数表现形式
示例1

输入

10 1

输出

10

说明

10/1 = 10 
示例2

输入

1 2

输出

0.5

说明

1/2 = 0.5 
示例3

输入

1 3

输出

0.(3)

说明

1/3 = 0.333333... 
示例4

输入

1 6

输出

0.1(6)

说明

1/6 = 0.16666666.... 
示例5

输入

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;
}

发表于 2019-07-10 14:30:36 回复(0)
import java.util.*;
public class Print_cycle {
        public static void main(String[] args){
            Scanner scan = new Scanner(System.in);
            int a = scan.nextInt();
            int b = scan.nextInt();
            if(a%b ==0){
                System.out.println(""+a/b);             //若为整数,则直接输出
            }else{
                int c = a;
                ArrayList<Integer> xiaoshu = new ArrayList<Integer>();        //记录各位小数
                HashMap<Integer,Integer> pos = new HashMap<Integer,Integer>();    //HashMap用于寻找重复位置
                int looppos = -1;
                c=c%b;
                while(c!=0){
                    if(pos.containsKey(c))
                    {
                        looppos = pos.get(c);          //若重复,则寻找之前的位置并跳出循环
                        break;
                    }else{
                        xiaoshu.add(c*10/b);                //计算一位小数,并将其放入arraylist
                        pos.put(c,pos.size());         //将小数对应位置进行记录
                    }
                    c=c*10%b;
                }
                if(looppos==(-1)){
                    System.out.print(a/b);
                    System.out.print('.');
                    for(int i:xiaoshu){
                        System.out.print(i);
                    }
                }else{
                    System.out.print(a/b);
                    System.out.print('.');
                    for(int j=0;j<looppos;j++){
                        System.out.print(xiaoshu.get(j));
                    }
                    System.out.print('(');
                    for(int k=looppos;k<xiaoshu.size();k++){
                        System.out.print(xiaoshu.get(k));
                    }
                    System.out.print(')');
                }
                
            }
        }
    }
发表于 2019-03-17 13:09:05 回复(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;
}
编辑于 2019-03-30 17:12:46 回复(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;	
} 

发表于 2020-08-24 14:17:47 回复(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);
            }
        }
    }
}
发表于 2019-12-05 17:31:23 回复(0)
#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;
}

发表于 2019-12-04 01:36:36 回复(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))

发表于 2019-08-29 14:40:42 回复(0)

如果是整除直接输出 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());
    }

}
发表于 2019-08-09 23:38:50 回复(0)
#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;
}

编辑于 2019-03-24 22:01:31 回复(0)
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);
    }
}
发表于 2020-02-19 12:19:48 回复(0)
这题目要耐心    余数如果重复出现说明此位置是循环节 用一个map保存每个余数出现的位置 在此位置加"("即可
#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

*/


编辑于 2019-09-01 16:47:58 回复(0)

当某个余数重复出现时,说明为无限循环小数。需要记录每个余数的位置。查看详细题解请移步至 ABC

发表于 2024-06-24 21:04:39 回复(0)
# 精华答案的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())

发表于 2021-08-27 15:59:35 回复(0)
// 方法很常规 寻求更好解法
#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;
    
}

发表于 2020-06-09 18:28:03 回复(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());
    }
}

发表于 2020-04-11 22:36:45 回复(0)
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))

发表于 2020-03-08 11:28:04 回复(0)

Python 3 版本 

按照正常除法的思路来写循环,

每次把商和余数记录在L1,L2中 

当余数重复出现的时候,说明出现循环,

记下重复出现的余数在L2中的位置index 在L1中,第0个元素是小数点左侧的数,0~index+1是括号左侧的数,index+1~最后是括号内的数

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:]))


编辑于 2020-02-17 22:33:11 回复(0)
#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);
    }
}  //综上所有的分数都是有理数,终于明白了
发表于 2019-10-08 17:18:00 回复(0)
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);
		
	}
}

发表于 2019-09-13 10:18:15 回复(0)
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(")")

发表于 2019-08-26 16:20:27 回复(0)