zoukankan      html  css  js  c++  java
  • 埃及分数 解题报告

    【杂言】:

    我是真的不想写了,但是,我挂了,挂的很彻底,30分钟找思路,1个小时修了三遍码,全挂了,被迫看题解,我真是醉了,一到分母,则为坟墓,(可能上天不想让我充当别人的分母吧)(UVA)的题,真的太狗了,好倒是挺好,这个输出就 ,,,算了,不吐槽了,但是我看了题解,看了题解就要写解题报告,这是习惯。


    【题目描述】:

    给定一个分数 (dfrac{a}{b}),然后给定 (k) 个数 (q_i)
    要求把 (dfrac{a}{b}) 分为几个不同的分子为 (1) 的最简分数,要求分成的分数的分母中不能出现 (q_i)
    本题有 (t) 组数据, (t le 100)
    其他数据范围: (2 le a < b le 876)(0 le k le 5)(gcd(a,b)=1)(2 le q_i le 1000)


    【思路分析】:

    想想,对于分数的分解问题,有没有好的数学方法去解决,因为往往数学能够解决的,信息中也就太简单了, 显然, 数学中也没有什么好方法,看到了 数据总共也不是很大,那么也就是只能搜索了,

    对于搜索,朴素的搜索我写挂了(@ο@) ~, 悲伤的事情,想起就是难过的经历。

    至于这道题的朴素写法, 那就是枚举有关(这里姑且说为有关)的分母,然后对于每一个分母相加起来,看看是否是可以与给定的数值相等, 如果可以,那就进行比较,同时确保这一个分母可以用和比较是否用这个分母是最优的 。 --- 这就是最朴素的搜索思路了。

    然后便是有关分母的枚举上界和下界问题 , 总不能枚举到 (10^9)的枚举吧

    有关其下界问题: 其下界也就是上一个用到的分母加 1 和 $frac{b imes y}{ b imes x - a imes y} $ 的最大值;

    解释一下 :
    上一次用到的分母加 1 , 不必说明了 。
    $frac{b imes y}{ b imes x - a imes y} $的推导,
    我们设其上一个字母为 (kkk)
    也就是说 (frac{a}{b}) + (frac{1}{kkk}) (leq frac{x}{y}) , 然后化简,不会可以找小学老师了(逃) ,
    有关其上界问题
    设的变量 ,$d=现在迭代的次数 dep是现在迭代到的数 $ ,
    那么(max = frac{frac{x}{y} - frac{a}{b} }{d - dep}) ,很显然 , 为了我们的精度, 我们可以转化为( imes)的形式;
    即为 : (b imes y imes (d - dep) + a imes max imes >= x imes b imes max) ,相当于一个终止条件嘛 , 也没必要去在意值。(值是你枚举的,管他干嘛?)


    【注意一下】:

    1. 很明显,我们选用 (set)去判别有没有这个值是更优的 (以(log_2 n)的)
    2. 更为明显, 分数必须要约分 , 不约分等于白做
    3. 他的输入输出是很毒瘤的 , 不能就随便输出的
    4. 不要忘记(set)迭代器转化为(int)类型 , 不然一直(CE)

    【Code】:

    暂且先放下代码,日后再补上,毕竟要去考试了呀~

    (TM)考试考炸了

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    //#include <algorithm> //打死我也没想到,algorithm我竟然定义了其中的关键词,为了解决这个问题,我决定,不用他,哈哈
    #include <cmath>
    #include <cstdlib>
    #include <queue>
    #include <set>
    #define inf 0x3f
    #define int long long
    #define QwQ printf("运行过了") ;
    using namespace std ;
    const int maxn = 1e5 ;
    inline int read()
    {
    	int x = 0 , f = 1 ; char ch = getchar() ;
    	while(!isdigit(ch)){ if(ch =='-') f = - 1 ; ch = getchar() ; }
    	while(isdigit(ch)) { x = x * 10 + ch - '0'; ch = getchar() ; }
    	return x * f ;
    }
    int gcd(int x,int y)
    {
    	return !y?x:gcd(y,x%y);
    }
    int lcm(int x , int y)
    {
    	return x / gcd(x,y) * y;  
    }
    //分数相减通分公式(a*x-b)/b*x
    int x , y , k , dep , tot = 0;
    bool vis[maxn] ;
    set<int> s ;
    vector<int> now ,ans ;
    void check()
    {
    	if(ans.empty() ||ans.size() > now.size())
    	{
    		ans = now ;	
    		return ;
    	} 
    	if(now.size() > ans.size() ) return ;
    	for(int i = (int)now.size() - 1 ; i >= 0 ; i--)
    	{
    		if(now[i]<ans[i])
    		{
    			ans = now ;
    			return ;
    		}
    		else if(now[i] > ans[i] )
    		{
    			return ;
    		}
    	}
    	return ;
    } 
    void prepare() // 多组数据每次都进行初始化 
    {
    	now.clear() ;
            ans.clear() ;
    	memset(vis , false ,sizeof(vis)) ;
    	s.clear() ;
    	return ;
    }
    void search(int d , int last , int a , int b) 
    {
    	if(a * y > b * x) 
    	{	
    		return ;
    	}
    	if(d >= dep)
    	{
    		if( a * y == b * x) check() ;
    		return ;
    	}
    	int p = gcd(a, b) ;
    	a /= p , b /= p ;
    	int head = max(last , y * b / (x * b - y *a) ) ;
    	for(int i = head ; b * y * (dep - d ) + a * i * y >= x * b * i ; i++)
    	{
    		if(s.count(i)) continue ;
    		now.push_back(i) ;
    		search(d + 1 , i + 1 , a * i + b , b * i) ;
    		now.pop_back() ;
     	}
     	return ;
    }
    void work()
    {
    	prepare() ;
    	x = read() , y = read() , k = read() ;
    	while(k--)
    	{
    		int m = read() ;
    		s.insert(m) ;
    	} 
    	int gcd_ = gcd( x , y ) ;
    	x /= gcd_ , y /= gcd_ ;
    	for(dep = 1 ; ans.empty() ; dep ++)
    	{
    		search(0 , 2 , 0 , 1) ; 
    	} 
    	printf("Case %lld: %lld/%lld=" , ++tot , x , y ) ;
    	printf("1/%lld", ans[0]) ;
    	for(int i = 1 ; i < (int)ans.size() ; i++)
    	{
    		printf("+1/%lld" , ans[i]) ;
    	}
    	printf("
    ") ; 
    	return ;
    } 
    signed main()
    {
    	int T = read() ;
    	while(T--)
    	{
    		work() ;
    	}
    	return 0;
    }
    
  • 相关阅读:
    链表-(1)
    爬虫(10-3)验证码图片识别
    爬虫10-2(多线程爬虫)
    分布式爬虫系统的架构(19)
    pipenv管理Python虚拟环境
    peewee-async集成到tornado
    Python3笔记051
    Python3笔记050
    Python3笔记049
    Python3笔记048
  • 原文地址:https://www.cnblogs.com/Zmonarch/p/14165594.html
Copyright © 2011-2022 走看看