decode

题目描述

给定一个正整数 k,有k 次询问,每次给定三个正整数n , e , d ,求两个正整数 p ,q ,使
n = p ×q e ×d =(p − 1) (q − 1) + 1

思路分析

这题是 暴力 数学
再看这两个式子(以下是初三数学)

解关于p,q二元二次方程组
n=pq
ed=(p-1)(q-1)+1
ed=(p-1)q-(p-1)1+1
ed=(p-1)q-(p-1)+1
ed=pq-q-p+1+1
ed=n-q-p+2
p=n/q
ed=n-q-n/q+2
edq=q(n-q-n/q+2)
edq=qn-qq-n+2q
edq=(-qq)+(n+2)q-n
(-qq)+(n+2)q-n=edq
(-qq)+(n+2-ed)q-n=0
a=-1
b=n+2-ed
c=-n
q=(-(n+2-ed)±sqrt(b^2-4ac))/2a
p=n/q

好了,写代码吧(注:一定要判断delta正负性)

#include<iostream>
#include<cmath>
#define int long long
using namespace std;
signed main(){
    freopen("decode.in","r",stdin);
    freopen("decode.out","w",stdout);
    int k;
    cin>>k;
    while(k--){
        int n,d,e;
        cin>>n>>d>>e;
        int a=-1;
        int b=n+2-e*d;
        int c=-n;
        int delta=b*b-4*a*c;
        if(delta<0){
            cout<<"NO\n";
            continue;
        }else if(delta==0){
            cout<<-b/(2*a)<<" "<<n/(-b/(2*a))<<"\n";
            continue;
        }else{
            int sq=sqrt(delta);
            int q1=(-b+sq)/(2*a);
            int p1=n/q1;
            int q2=(-b-sq)/(2*a);
            int p2=n/q2;
            if(p1>q1)
                swap(p1,q1);
            if(p2>q2)
                swap(p2,q2);
            if(p1>0&&q1>0&&p1*q1==n&&e*d==(p1-1)*(q1-1)+1){
                cout<<p1<<" "<<q1<<"\n";
            }else if(p2>0&&q2>0&&p2*q2==n&&e*d==(p2-1)*(q2-1)+1){
                cout<<p2<<" "<<q2<<"\n";
            }else{
                cout<<"NO\n";
            }
        }
    }
    return 0;
}

posted on 2024-06-27 16:18  可爱楷玩算法  阅读(27)  评论(0)    收藏  举报

导航