[AGC012C] Tautonym Puzzle 题解

原题链接:Tautonym Puzzle

前言

这道题是一道很有趣的构造题。我认为这道题的重点在于对题目要求的转化与转化过程中细节的处理。(有些细节问题也困惑了我很久)。

题意

构造一个字符串 \(S\) ,使 \(S\) 的所有子序列中,恰好有 \(N\) 个好串。

  • 好串:一个字符串能分成两个相同的字符串。

思路

我们可以构造一个形如 \(X\) 的字符串,满足:

  • 前一半为 \(1\)\(num\) 的一种排列

  • 后一半为 \(1\)\(num\)升序或降序排列

显然,题目要求前一半的上升/下降子序列的数量为 \(N\)

如何构造?我们拿后半段为升序排列来举例。

假设我们从小到大枚举字符,那么可以发现:

  • 当前字符如果放最前面,那么总方案数会 \(+1\)

  • 放最后面,方案数 \(×2\) 或方案数 \(×2+1\)

为什么有两种呢?这就是本题的重点了。

其实两种写法的区别在于对空串的计算。

第一种是先把空串加上,后面每次就不用计算空串的情况了。

第二种是先不加上空串,后面每次都考虑空串。

只要理解到这一点,本题思路就很清晰了。

总结

因为这道题可以升序或降序,先加空串或后加空串,所以共有四种写法。

Code

#include<bits/stdc++.h>
#define int long long
using namespace std;
const int MAXN = 1e3 + 10;	
int n, cnt1, cnt2, a[MAXN], b[MAXN], num = 101; 
signed main()
{
	cin >> n; n++;
	while (n > 1) {
		if (n & 1) a[++cnt1] = --num, n = n - 1;
		else b[++cnt2] = --num, n = n / 2;
	}
	cout << (100 - num + 1) * 2 << endl;
	for (int i = 1; i <= cnt1; i++) cout << a[i] << " ";
	for (int i = cnt2; i >= 1; i--) cout << b[i] << " ";
	for (int i = num ;i <= 100; i++) cout << i << " ";
    return 0;
}
#include<bits/stdc++.h>
using namespace std;
#define int long long
const int MAXN = 1e3 + 10;	
int n, cnt1, cnt2, a[MAXN], b[MAXN], num = 101; 
signed main()
{
	cin >> n; 
	while (n >= 1) {
		if (n & 1) a[++cnt1] = --num, n = (n - 1) / 2;
		else b[++cnt2] = --num, n = n - 1;
	}
	cout << (100 - num + 1) * 2 << endl;
	for (int i = 1; i <= cnt2; i++) cout << b[i] << " ";
	for (int i = cnt1; i >= 1; i--) cout << a[i] << " ";
	for (int i = num ;i <= 100; i++) cout << i << " ";
    return 0;
}
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int MAXN = 1e3 + 10;	
int n, cnt1, cnt2, a[MAXN], b[MAXN], num = 0; 
signed main()
{
	cin >> n; n++;
	while (n > 1) {
		if (n & 1) a[++cnt1] = ++num, n = n - 1;
		else b[++cnt2] = ++num, n = n / 2;
	}
	cout << num * 2 << endl;
	for (int i = 1; i <= cnt1; i++) cout << a[i] << " ";
	for (int i = cnt2; i >= 1; i--) cout << b[i] << " ";
	for (int i = num ;i >= 1; i--) cout << i << " ";
    return 0;
}
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int MAXN = 1e3 + 10;	
int n, cnt1, cnt2, a[MAXN], b[MAXN], num = 0; 
signed main()
{
	cin >> n; 
	while (n >= 1) {
		if (n & 1) a[++cnt1] = ++num, n = (n - 1) / 2;
		else b[++cnt2] = ++num, n = n - 1;
	}
	cout << num * 2 << endl;
	for (int i = 1; i <= cnt2; i++) cout << b[i] << " ";
	for (int i = cnt1; i >= 1; i--) cout << a[i] << " ";
	for (int i = num ;i >= 1; i--) cout << i << " ";
    return 0;
}
posted @ 2023-12-19 11:45  Creeper_l  阅读(13)  评论(0编辑  收藏  举报
  1. 1 イエスタデイ(翻自 Official髭男dism) 茶泡饭,春茶,kobasolo
  2. 2 世间美好与你环环相扣 柏松
  3. 3 True love tired
  4. 4 一笑江湖 (DJ弹鼓版) 闻人听書_
  5. 5 最好的安排 曲婉婷
  6. 6 星星在唱歌 司南
  7. 7 山川 李荣浩
  8. 8 On My Way Alan Walker
  9. 9 百战成诗 王者荣耀·100英雄官方群像献礼歌
  10. 10 雪 Distance Capper / 罗言
  11. 11 Edamame bbno$ / Rich Brian
  12. 12 半生雪 七叔-叶泽浩
  13. 13 Catch My Breath Kelly Clarkson
  14. 14 Love Is Gone SLANDER / Dylan Matthew
  15. 15 Endless Summer Alan Walker / Zak Abel
  16. 16 悬溺 葛东琪
  17. 17 风吹丹顶鹤 葛东琪
  18. 18 Normal No More TYSM
  19. 19 哪里都是你 队长
  20. 20 Stronger Kelly Clarkson
  21. 21 廖俊涛
  22. 22 消愁 毛不易
  23. 23 The Runner Yubik
  24. 24 踏山河 七叔-叶泽浩
  25. 25 Waiting For Love Avicii
  26. 26 在你的身边 盛哲
  27. 27 Dream It Possible Delacey
  28. 28 凄美地 郭顶
  29. 29 满天星辰不及你 ycc
  30. 30 侧脸 于果
  31. 31 阿拉斯加海湾 蓝心羽
  32. 32 虞兮叹 闻人听書_
  33. 33 离别开出花 就是南方凯
  34. 34 盗墓笔记·十年人间 李常超 (Lao乾妈)
踏山河 - 七叔-叶泽浩
00:00 / 00:00
An audio error has occurred, player will skip forward in 2 seconds.