求助一道规律站外题(蒟蒻已经做了1个多小时了)
  • 板块灌水区
  • 楼主Hoks
  • 当前回复1
  • 已保存回复1
  • 发布时间2022/7/21 20:28
  • 上次更新2023/10/27 19:01:40
查看原帖
求助一道规律站外题(蒟蒻已经做了1个多小时了)
551100
Hoks楼主2022/7/21 20:28

来自于模拟赛的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:28
加载中...