题目链接:http://202.197.224.59/OnlineJudge2/index.php/Problem/read/id/1236
题目大意:
给出一个0,1之间小数,求最接近该小数的分数,分母规定在1到1000。
注意题目有10000个数据。。。
解题思路:
预处理一个分数和对应的小数表并且排好序,按照题目要求,先按分数值大小排序,再按分子分母大小排,对于每次查询进行二分查找这个表得到一个pos值,再枚举该位置的1000到后1000个数,找出最接近的分数,就是答案。
Code:
/* W w w mm mm 222222222 7777777777777 */
/* W w w w m m m m 222 22 7777 */
/* w w w w m m m m 22 777 */
/* w w w w m m m m 22 77 */
/* w w w w m m m m 222 77 */
/* w w w w m m m m 222 77 */
/* w w w w m m m m 222 77 */
/* w w w w m m m m 222 77 */
/* w w w w m m m m 222 77 */
/* ww ww m mm m 222222222222222 77 */
//#pragma comment(linker, "/STACK:102400000,102400000")
//C++
//int size = 256 << 20; // 256MB
//char *p = (char*)malloc(size) + size;
//__asm__("movl %0, %%esp\n" :: "r"(p));
//G++
#include<set>
#include<map>
#include<queue>
#include<stack>
#include<ctime>
#include<deque>
#include<cmath>
#include<vector>
#include<string>
#include<cctype>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<sstream>
#include<iostream>
#include<algorithm>
#define REP(i,s,t) for(int i=(s);i<=(t);i++)
#define REP2(i,t,s) for(int i=(t);i>=s;i--)
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef unsigned long ul;
int T;
double x;
int gcd(int x,int y)
{
return x==0?y:gcd(y%x,x);
}
struct xxx
{
double idx,idy;
double res;
xxx (double _idx=0,double _idy=0,double _res=0):idx(_idx),idy(_idy),res(_res){}
bool operator < (const xxx &r)const
{
if((double)fabs(res-r.res)<1e-12)
{
if(idx==r.idx)
{
return idy<r.idy;
}
return idx<r.idx;
}
return res<r.res;
}
};
bool vis[1000005];
vector<xxx>ans;
vector<double>a;
void fuck()
{
ans.clear();
for(double i=1;i<=1000;i++)
{
for(double j=0;j<=i;j++)
{
int k=gcd((int)i,(int)j);
if(j>0)
{
ans.push_back(xxx(j/(double)k,i/(double)k,j/i));
}
else
{
ans.push_back(xxx(j,i,j/i));
}
}
}
sort(ans.begin(),ans.end());
a.clear();
for(int i=0;i<ans.size();i++)
{
a.push_back(ans[i].res);
}
}
int main()
{
#ifdef ONLINE_JUDGE
#else
freopen("test.in","r",stdin);
#endif
fuck();
scanf("%d",&T);
while(T--)
{
scanf("%lf",&x);
int pos=lower_bound(a.begin(),a.end(),x)-a.begin();
int p=pos;
int d=1000;
for(int i=-d;i<=d;i++)
{
if(pos+i<0||pos+i>a.size()-1)
{
continue;
}
if(fabs(a[pos+i]-x)<fabs(a[p]-x))
{
p=pos+i;
}
}
printf("%d/%d\n",(int)ans[p].idx,(int)ans[p].idy);
}
return 0;
}