列表

详情


NC15337. Interesting Set

描述

Mr.Frog is researching integers.

He converts two integers X and Y into binary system without leading zeros, if they have the same quantity of 0 and the same quantity of 1 in the binary system, Mr.Frog will think these two integers are friendly.               

For example, 5(10) = 101(2) and 6(10) = 110(2), both of them have two 1 and one 0 in the binary system, so Mr.Frog thinks 5 and 6 are friendly.              

Now, Mr.frog gets an integer N and defines a sorted set S. The sorted set S consists of integers which are friendly with N and bigger than N. He wants to know what is the Kth integer in S.                

Because Mr.Frog is on his way back from Hong Kong to Beijing, he wants to ask you for help.

输入描述

The first line contains an integer T, where T is the number of test cases. T test cases follow. 
For each test case, the only line contains two integers N and K.
         
• 1 ≤ T ≤ 200. 
• 1 ≤ N ≤ 1018
• 1 ≤ K ≤ 1018

输出描述

For each test case, print one line containing “Case #x: y”, where x is the test case number (startingfrom 1) and y is the Kth integer in the sorted set S. If the integer he wants to know does not exist, y is“ IMPOSSIBLE”.

示例1

输入:

2
9 2
7 4

输出:

Case #1: 12
Case #2: IMPOSSIBLE

原站题解

上次编辑到这里,代码来自缓存 点击恢复默认模板

C++14(g++5.4) 解法, 执行用时: 4ms, 内存消耗: 508K, 提交时间: 2020-02-10 15:36:49

#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#define iinf 0x3f3f3f3f
#define linf (1ll<<60)
#define eps 1e-8
#define maxn 110
#define maxe 1000010
#define cl(x) memset(x,0,sizeof(x))
#define rep(i,a,b) for(i=a;i<=b;i++)
#define em(x) emplace(x)
#define emb(x) emplace_back(x)
#define emf(x) emplace_front(x)
#define fi first
#define se second
#define de(x) cerr<<#x<<" = "<<x<<endl
using namespace std;
using namespace __gnu_pbds;
typedef long long ll;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;
ll read(ll x=0)
{
    ll c, f(1);
    for(c=getchar();!isdigit(c);c=getchar())if(c=='-')f=-f;
    for(;isdigit(c);c=getchar())x=x*10+c-0x30;
    return f*x;
}
ll dig[maxn], c[maxn][maxn], ans[maxn], tot;
ll C(ll n, ll m)
{
    if(n<0 or m<0 or m>n)return 0;
    return c[n][m];
}
ll count()
{
    ll ans=0, i, c[]={0,0};
    rep(i,1,tot)c[dig[i]]++;
    c[1]--;
    for(i=tot-1;i;i--)
    {
        if(dig[i])ans+=C(c[0]-1+c[1],c[1]);
        c[dig[i]]--;
    }
    return ans+1;
}
ll construct(ll res)
{
    ll i, c[]={0,0};
    rep(i,1,tot)c[dig[i]]++;
    c[1]--;
    if(C(c[0]+c[1],c[0])<res)return -1;
    ans[tot]=1;
    for(i=tot-1;i;i--)
    {
        ll t=C(c[0]-1+c[1],c[1]);
        if(res>t)
        {
            res-=t;
            ans[i]=1;
            c[1]--;
        }
        else
        {
            ans[i]=0;
            c[0]--;
        }
    }
    return 0;
}
int main()
{
    ll n, k, T, i, j, kase;
    rep(i,0,maxn-1)c[i][0]=1;
    rep(i,1,maxn-1)rep(j,1,i)c[i][j]=c[i-1][j-1]+c[i-1][j];
    T=read();
    rep(kase,1,T)
    {
        n=read(), k=read();
        tot=0;
        while(n)
        {
            dig[++tot]=n&1;
            n>>=1;
        }
        ll t=count();
        ll ret=construct(t+k);
        // de(t);
        printf("Case #%lld: ",kase);
        if(ret==-1)printf("IMPOSSIBLE\n");
        else
        {
            ll t=0;
            rep(i,1,tot)t=t+(ans[i]<<i-1);
            // rep(i,1,tot)printf("%lld",ans[i]); putchar(32);
            printf("%lld\n",t);
        }
    }
    return 0;
}

C++11(clang++ 3.9) 解法, 执行用时: 5ms, 内存消耗: 488K, 提交时间: 2018-03-29 21:26:42

#include<bits/stdc++.h>

using namespace std;
typedef long long ll;
ll query,kase,n,k,c[64][64],p,q,d[64],r,w,s,t,ans;

int main()
{
    c[0][0]=1;
    for (int i=1;i<64;i++)
    {
        c[i][0]=c[i][i]=1;
        for (int j=1;j<i;j++)
            c[i][j]=c[i-1][j-1]+c[i-1][j];
    }
    scanf("%d",&query);
    while (query--)
    {
        scanf("%lld%lld",&n,&k); r=0; p=q=0;
        printf("Case #%d: ",++kase);
        while (n) {
            d[r++]=n&1;
            n>>=1;
        }
        for (int i=0;i<r-1;i++) if (d[i]) p++; else q++;
        s=p; t=q; w=1;
        for (int i=r-2;i>=1;i--)
            if (d[i]) w+=c[p+q-1][p],p--; else q--;
        w+=k;
        if (w>c[s+t][s]) printf("IMPOSSIBLE\n");
        else {
            ans=1ll<<(r-1);
            for (int i=r-2;i>=0;i--)
                if (t==0||c[s+t-1][s]<w) w-=c[s+t-1][s],s--,ans+=(1ll<<i); else t--;
            cout << ans << endl;
        }
    }
    return 0;
}

上一题