来自于模拟赛的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;
}
样例没问题,补充样例有问题