csu1941(exgcd)

1 篇文章 0 订阅

题目链接:点击打开链接

// csu 1941
// 大概题意:求一个a* f[i]+b* f[i- 1]= g的解,b为第一关键字最小,a为第二关键字


#include <iostream>
#include <algorithm>
#include <fstream>
#include <sstream>
#include <iomanip>
#include <cstdio>
#include <vector>
#include <cstring>
#include <cmath>
#include <queue>
#include <stack>
#include <set>
#include <map>
#define ll long long

using namespace std;

ll f[50];

ll gcd(ll a, ll b)
{
    if(!b) return a; else return gcd(b, a% b);
}

void exgcd(ll a, ll b, ll &d, ll &x, ll &y)
{
    if(!b) { d= a; x= 1; y= 0; }
    else { exgcd(b, a% b, d, y, x); y-= x* (a/ b); }
}

int main()
{
    f[1]= 1; f[2]= 1;
    for(int i= 3; i<= 50; i++) f[i]= f[i- 1]+ f[i- 2];
    int T; cin >> T;
    while(T--)
    {
        ll g, ansa= 1000000007, ansb= 1000000007, anst; scanf("%lld", &g);
        for(int i= 1; i<= 50; i++)
            if(g% gcd(f[i], f[i+ 1])== 0)                   // 其实由于斐波那契相邻两项互质(没有证明)可以省去这一步,并且之后的d都省略
            {
                ll x, y, d, a= f[i], b= f[i+ 1];
                exgcd(a, b, d, x, y);
                x*= g/ d; y*= g/ d;                        //调用后,(x,y)为最靠近零的整数解
                if(x<= 0)
                {
                    ll k= b/ d;
                    ll xx= (x% k+ k)% k;
                    ll t= (xx- x)/ k;
                    x= xx; y-= t* a/ d;
                }
                /*
                ll t= abs(y- x)/(a/ d+ b/ d);
                if(x< y) { x+= b* t/ d; y-= a* t/ d; }    //这几行很丑!完全抄的非正解
                else                                      // y= y0- a/ d* t x= x0+ b/ d* t;
                {                                         // y> x 然后推出t的范围.......至于这样做为什么对完全不解;
                    if(abs(y- x)% (a/ d+ b/ d)) t++;      //应该是因为exgcd本身的性质吧!不过好像懂一点点了,
                    x-= b* t/ d; y+= a* t/ d;
                }
                */

                ll t= (y- x)/(a/ d+ b/ d);                 //这是我自己改的,貌似科学了点,但是还是wa
                ll x0= x, y0= y;                           //就是说abs(y0- x0)% (a/ d+ b/ d)不是整除的时候,c++是向0取整,当t为负时所以这时要t--
                x=x0+ b* t/ d; y=y0- a* t/ d;              //貌似对了!嘎嘎嘎嘎嘎嘎!!!!!
                if((y0< x0) && abs(y0- x0)% (a/ d+ b/ d)) { t--; x=x0+ b* t/ d; y=y0- a* t/ d;}
                if((x> 0) && (y>= x) && ((y< ansb) || (y== ansb && x< ansa)))
                {
                    ansb= y; ansa= x; anst= a* t;
                }
            }
        printf("%lld %lld\n", ansa, ansb);
    }
    return 0;
}



  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
资源包主要包含以下内容: ASP项目源码:每个资源包中都包含完整的ASP项目源码,这些源码采用了经典的ASP技术开发,结构清晰、注释详细,帮助用户轻松理解整个项目的逻辑和实现方式。通过这些源码,用户可以学习到ASP的基本语法、服务器端脚本编写方法、数据库操作、用户权限管理等关键技术。 数据库设计文件:为了方便用户更好地理解系统的后台逻辑,每个项目中都附带了完整的数据库设计文件。这些文件通常包括数据库结构图、数据表设计文档,以及示例数据SQL脚本。用户可以通过这些文件快速搭建项目所需的数据库环境,并了解各个数据表之间的关系和作用。 详细的开发文档:每个资源包都附有详细的开发文档,文档内容包括项目背景介绍、功能模块说明、系统流程图、用户界面设计以及关键代码解析等。这些文档为用户提供了深入的学习材料,使得即便是从零开始的开发者也能逐步掌握项目开发的全过程。 项目演示与使用指南:为帮助用户更好地理解和使用这些ASP项目,每个资源包中都包含项目的演示文件和使用指南。演示文件通常以视频或图文形式展示项目的主要功能和操作流程,使用指南则详细说明了如何配置开发环境、部署项目以及常见问题的解决方法。 毕业设计参考:对于正在准备毕业设计的学生来说,这些资源包是绝佳的参考材料。每个项目不仅功能完善、结构清晰,还符合常见的毕业设计要求和标准。通过这些项目,学生可以学习到如何从零开始构建一个完整的Web系统,并积累丰富的项目经验。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值