求助站外规律题
  • 板块学术版
  • 楼主Hoks
  • 当前回复4
  • 已保存回复4
  • 发布时间2022/7/21 20:43
  • 上次更新2023/10/27 19:01:20
查看原帖
求助站外规律题
551100
Hoks楼主2022/7/21 20:43

来自于模拟赛的t2,题面如下:

2.二数

【问题描述】 有一种正整数,可以表示成两个数 x 和 y 的乘积,且 x 和 y 表示成二进制时,对应的 0 和 1 的个数相同。比如 30=5*6,5 和 6 表示成二进制时,5 有一个 0 和二个 1,6 也一样。

把这种数称之为“二数”,平方数也是“二数”。求第 k 小的“二数”。

【输入格式】 第一行一个整数 Q,表示询问的次数。接下来 Q 行,每行一个整数 c,表示一个询问。

【输出格式】 输出共 Q 行,每行表示一个对应的答案。

【输入样例】 3 2 45

【输出样例】 4 16 25

【补充输入】 3 10 100 1000

【补充输出】 81 1750 26460

tip:输出要换行,比较懒就不整了

【数据范围】k<=1000000,q<10

蒟蒻代码:

#include<bits/stdc++.h>
#define int long long
using namespace std;
struct node
{int x,y;};
struct node1
{
    int x;
    bool operator<(const node1 &a)
        const{return a.x<x;}
};
int a[14][14],b[14][14],c[14][14];
int d[1000010],e[14];
map<int,bool> mp[14];
int q,tot,tot1,tot2;
bool cmp(int x,int y){return x<y;}
node xz(int x)//xz:寻找
{
    for(int i=1;i<=13;i++)
        for(int j=1;j<=13;j++)
            if(c[i][j]>=x) return (node){i,j};
    return (node){-1,-1};
}
void zs(int step,int sum1,int sum)//zs:造数
{
    //cout<<step<<" "<<sum1<<" "<<sum<<endl;
    if(step>tot1+tot2) return ;
    if(step==tot1+tot2&&sum1==tot1){d[++tot]=sum;return ;}
    if(!mp[step][sum]){mp[step][sum]=1;zs(step+1,sum1,sum);mp[step][sum]=0;}
    if(!mp[step][sum+e[step]]&&sum1<tot1){mp[step][sum+e[step]]=1;zs(step+1,sum1+1,sum+e[step]);mp[step][sum+e[step]]=0;}
}
void zhsc(int x)//zhsc:组合输出
{
    priority_queue<node1>q;
    int book[100010]={0};
    sort(d+1,d+1+tot,cmp);//for(int i=1;i<=tot;i++) cout<<d[i]<<" ";cout<<endl;
    for(int i=1;i<=tot;i++)
        for(int j=1;j<=tot;j++)
            if(!book[d[i]*d[j]])
                book[d[i]*d[j]]=1,q.push((node1){d[i]*d[j]});//,cout<<d[i]*d[j]<<" ";
    while(x!=1) q.pop(),x--;
    cout<<q.top().x<<endl;
}
int read()
{
    char c=getchar();int x=0;
    while(!isdigit(c)) c=getchar();
    while(isdigit(c)) x=(x<<1)+(x<<3)+(c^48),c=getchar();
    return x;
}
/*1000000的题目一定是要找规律,手画发现了杨辉三角
从而推出了初始化:a是初始三角,b是算总数,c是前缀和
a[i][j]表示1有i-j+1个,0有j-1个的二进制数总数。
*/
signed main()
{
    e[1]=1;
    for(int i=2;i<=13;i++) e[i]=e[i-1]*2;
    for(int i=1;i<=13;i++)
    {
        a[i][1]=a[i][i]=1;b[i][1]=b[i][i]=0;
        for(int j=2;j<i;j++) a[i][j]=a[i-1][j]+a[i-1][j-1],b[i][j]=a[i][j]*(a[i][j]-1)/2;
    }
    for(int i=1;i<=13;i++)
    {
        c[i][1]=c[i-1][i-1]+b[i][1]+a[i][1];cout<<c[i][1]<<" ";
        for(int j=2;j<=i;j++) c[i][j]+=b[i][j]+a[i][j]+c[i][j-1],cout<<c[i][j]<<" ";
        cout<<endl;
    }
    q=read();
    while(q--)
    {
        int x=read();
        node y=xz(x);tot2=y.x-y.y,tot1=y.x-tot2,tot=0;
        if(y.y!=1) x=x-c[y.x][y.y-1];
        else x=x-c[y.x-1][y.x-1];
        //if(x==0) x=1;
        cout<<y.x<<" "<<y.y<<" "<<tot1<<" "<<tot2<<" "<<x<<" "<<e[y.x]<<endl;
        zs(1,1,e[y.x]);
        zhsc(x);
    }
    return 0;
}

样例没问题,补充样例有问题

2022/7/21 20:43
加载中...