Problem 2223 神奇的计算器
Accept: 11 Submit: 79
Time Limit: 1000 mSec Memory Limit : 32768 KB
Problem Description
为了帮助正在学习除法的表弟,Yellowstar想制作一个计算器,它能给出整数除法的完整结果。
具体来说,给出两个整数m、n:
如果m/n是整数或有限小数,那么直接输出它的值。
如果m/n是无限小数,那么输出小数点后到第一个最小循环节为止,并用”()”把最小循环节括起来。
Input
输入第一行为一个正整数T,表示有T组测试数据。
接下去T行,每行为一组数据。每行两个正整数m、n,含义如上。
T<=15,1<=m,n<=2^31-1。
Output
每个样例一行,输出答案。
注意计算器的屏幕最多能输出1 000 000个字符(包括小数点和括号,不包括结尾的换行),如果某组数据的结果超过了这个长度,那么该组数据输出”Too long”而不是原答案。
Sample Input
44 21 5123 7652 1380779
Sample Output
20.20.1(6078431372549019)Too long
Source
FOJ有奖月赛-2016年4月(校赛热身赛)思路:该题目有4种情况1、m%n == 0;对于这种情况最简单了,直接输出m/n;然后其他情况就需要模拟一下除法来保存m/n的整数部分和小数部分,n是固定不变的,而你识不断变化的,根据鸽巢原理就可以知道肯定存在m变化的过程中会出现一个m'/n == m/n,这就意味着循环节出现了,但我们每次需要标记m,而m的范围是1<=m<=2^31-1,我们开不了这么大的数组,只能用Hash表把新得到的m'存好,没得到了一个m'就通过索引去寻找当前的m'是是否被标记了,后面就很简单了。
代码:
#include <cstdio>
#include <cstring>
typedef long long ll;
const int maxn = 1000000+1024;
const int maxm = 1000007;
int Head[maxn],Next[maxn],top;
ll key[maxn],x,y,a,b,t,bit[maxn];
ll n,cnt;
bool getVis(ll s)
{
int pos = (int)s%maxm;
for(int i = Head[pos];i;i = Next[i])
{
if(key[i] == s) return true;//当前的Hash中存在这个数了,返回true
}
return false;//没有就返回false
}
void Intert(ll s)
{
int pos = (int)s%maxm;//获取索引
Next[top++] = Head[pos];
Head[pos] = top;
key[top] = s;
}
int main()
{
#ifdef CDZSC_June
freopen("t.txt","r",stdin);
#endif // CDZSC_June
scanf("%I64d",&n);
while(n--)
{
top = 0; memset(Head,0,sizeof(Head));
cnt = 0;
scanf("%I64d%I64d", &a, &b);
x = a,y = b;
if(x%y == 0){//能够整除,直接输出
printf("%I64d\n",x/y);
}
else
{
bit[cnt++] = x/y;
a %= b;
bit[cnt++] = a*10/b;
Intert(0); Intert(a);
a = a*10%b;
while(!getVis(a))
{
bit[cnt++] = a*10/b;
Intert(a), a = a*10%b;
if(cnt > 1000000)break;
}
if(a == 0)//有限小数,直接输出数组里面的元素
{
printf("%I64d.",bit[0]);
for(int i = 1; i<cnt; i++)
{
printf("%I64d",bit[i]);
}
puts("");
}
else
{
t = a;
if(cnt > 1000000){//循环节过长了,输出Too long
puts("Too long");
}
else{//有限循环小数,输出该数和它的循环节
printf("%I64d.",bit[0]);
for(int i =1;i<cnt;i++)
{
if(bit[i] == a*10/b) break;
printf("%I64d",bit[i]);
}
printf("(");
do
{
printf("%I64d",a*10/b);
a = a*10%b;
} while (a != t);
printf(")\n");
}
}
}
}
return 0;
}