裸题

Time Limit : 3000/1000ms (Java/Other)   Memory Limit : 65535/32768K (Java/Other)
Total Submission(s) : 12   Accepted Submission(s) : 3

Problem Description

Here is no naked girl nor naked runners, but a naked problem: you are to find the K-th smallest element in the set of all irreducible fractions p/q,with 0<p<q<=N.

Input

The first line of input is an integer T(T<=1000), indicating there are T cases.
For each cases, there is one line with two positive integers N and K(1<=K<N<=100000).

Output

For each case, output one line containing the answer.

Sample Input

4
5 1
5 2
5 3
5 4

Sample Output

1/5
1/4
1/3
2/5

这道题目用的是类似于栈的方法AC的,之前用深搜超时,看别人的代码找出一个规律,1/n  < 1/n-1,  k1/n1>(k1+k2)/(n1+n2) (n1>n2, k1>k2),根据题目我画出树状图帮助理解


这个是我AC过的代码

#include <iostream>
#include <stdio.h>
const int SIZE = 1000000;
using namespace std;

int n, k, i, visit[SIZE];
int p, q, f_Lp[SIZE], f_Lq[SIZE], f_Rp[SIZE], f_Rq[SIZE];
int main()
{
    int T;
    cin >> T;
    while(T--)
    {
        cin >> n >> k;
        f_Lp[0] = 0; f_Lq[0] = 1;
        f_Rp[0] = 1; f_Rq[0] = 1;
        i = 0;  visit[0] = 0;
        while(true)
        {
            p = f_Lp[i]+f_Rp[i];
            q = f_Lq[i]+f_Rq[i];
           // cout << f.p << "/" << f.q << " A" << endl;
            if(q > n)
                i--;
            else if(visit[i]==0)
            {
                f_Lp[i+1] = f_Lp[i];
                f_Lq[i+1] = f_Lq[i];
                f_Rp[i+1] = p;
                f_Rq[i+1] = q;
                visit[i]++;
                visit[i+1] = 0;
                i++;
            }
            else
            {
                k--;
                //cout << f.q << " k=" << k << endl;
                if(k==0)    break;
                f_Lp[i] = p;
                f_Lq[i] = q;
                visit[i] = 0;
            }
        }
        printf("%d/%d\n", p, q);
        //cout << ans.p << "/" << ans.q << endl;
    }
    return 0;
}


这个帮助大家理解,把几个注释去掉可以看到运行情况

#include <iostream>
#include <stdio.h>
using namespace std;

struct node
{
    int p, q;
    node operator + (const node &A)
    {
        node B;
        B.p = p + A.p;
        B.q = q + A.q;
        return B;
    }
};
bool DFS(node, node);
int n, k;
node ans;

int main()
{
    int T;
    cin >> T;
    while(T--)
    {
        cin >> n >> k;
        node f = (node){0, 1};
        node nf = (node){1, 1};
        DFS(f, nf);
        printf("%d/%d\n", ans.p, ans.q); //竟然输出地址,搞笑了
        //cout << ans.p << "/" << ans.q << endl;
    }
    return 0;
}

bool DFS(node f1, node f2)
{
    //cout << "left: " << f1.p << " " << f1.q;
    //cout << "  right: " << f2.p << " " << f2.q << endl;
    if(k==0)    return 1;
    node nf = f1 + f2;
    if(nf.q > n)    return 0;
    //cout << nf.q << " " << n << endl;
    //cout << endl;
    //cout << "A nf: " << nf.p << " " << nf.q << endl;
    bool flag = DFS(f1, nf);
    if(flag)    return 1;
    else
    {
        k--;
        cout << "k=" << k << endl;
        if(k==0)
        {
            ans = nf;
            //cout << ans.p << "A " << ans.q << endl;
            //cout << nf.p << "B " << nf.q << endl;
            return 1;
        }
    }
    //cout << "B nf: " << nf.p << " " << nf.q << endl;
    return DFS(nf, f2);
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值