题目大意:
输入 t 表示有 t 组数据,对于每组数据输入n,你需要用1 3 7 来构造一个序列,使得其中恰好有 n 个 1337 的子序列,输出构造好的序列。
解题思路:
范围有1e9,想要只通过n个1和n个7和一个33构造是不可能的,需要观察下33的规律,发现n个3,能构造n(n - 1)/ 2 个33的子序列,所以我们可以构造形如 1337333337这样的子序列,那么总1337的个数就等于所有33构造出来的个数 + 前面7的个数,7穿插在中间就可以达到加的效果了。大概45000个3能构造1e9左右,先打一个表,把1e9之内以及刚好超过1e9的构造数打出来,找到刚好大于等于n的a[num],表示num - 1个3能构造出离n最近的序列个数。前面输出133和(n - a[num - 1])个7,后面则输出a[num - 1] - 2 个3,再输出 7 即可。因为前面已经贡献了2个3所以要 - 2。
Code:
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <vector>
#include <queue>
#include <set>
#include <map>
using namespace std;
const int mod = 1e9 + 7;
const int N = 1e6;
const int inf = 0x3f3f3f3f;
typedef long long ll;
ll a[N];
void init()
{
memset(a, 0, sizeof a);
for (int i = 2; i * (i - 1) / 2 <= 1e9 + 1e7; i ++)
a[i] = i * (i - 1) / 2;
}
int main()
{
init();
int t;
cin >> t;
while (t--)
{
int n;
cin >> n;
int num = 2;
while((n - a[num]) >= 0) num++;
int s = (n - a[num - 1]);
printf("133");
for (int i = 1; i <= s; i ++)
putchar('7');
for (int i = 1; i < num - 2; i ++)
putchar('3');
putchar('7');
cout << endl;
}
return 0;
}