Codeforces 1202D - Print a 1337-string...(构造 + 思维)

在这里插入图片描述

题目大意:

输入 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;
}

猜你喜欢

转载自blog.csdn.net/aezakmias/article/details/107590157