- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
问题是找到一个 1<=n<=50000 元素的数字序列(1 到 10^5),如果可以选择这样一个子序列,那么剩余的元素将创建所选子序列的另一个拷贝。换句话说,如果原始序列是由某些子序列的两个拷贝交织而成的。如果是这样,我们必须另外打印原始子序列。我的想法是天真地将同类的所有其他数字分成两个子序列。因此,例如,第一个子序列将得到第 1 个 5、第 3 个 5 和第 1 个 4,第二个子序列将得到第 2 个 5、第 4 个 5 和第 2 个 4。我认为该序列不能表示为两个拷贝的组合,如果它其中有奇数个数字。然而,整个方法都是错误的,很少能给出好的答案;
请帮我找到一个更聪明的算法来实际解决问题。我为更好地理解 (C++) 而采用的朴素方法:
#include<iostream>
#include<string>
#include<algorithm>
#include<vector>
using namespace std;
int main()
{
ios_base::sync_with_stdio(0);
cin.tie(0);
int n;
cin >> n;
vector<short> arr(n);
for (int i = 0; i < n; ++i)
{
cin >> arr[i];
}
vector<vector<unsigned short>> positions(10001, vector<unsigned short>(0));
for (int i = 0; i < n; ++i)
{
positions[arr[i]].push_back(i);
}
vector<unsigned short> out;
for (int i = 0; i <= 10000; ++i)
{
if (positions[i].size() % 2)
{
cout << "NO" << "\n";
return 0;
}
for (int j = 0; j < positions[i].size(); j += 2)
{
out.push_back(positions[i][j]);
}
}
sort(out.begin(), out.end());
cout << "YES" << "\n";
for (int i = 0; i < out.size(); ++i)
{
cout << arr[out[i]] << " ";
}
}
最佳答案
您可以使用回溯来解决这个问题。还有一些优化可能。您知道第一个数字必须是序列的第一个数字。因此,该数字第一次出现和第二次出现之间的所有字母都必须按顺序排列。对于序列中的最后一个数字也是如此。此外,您可以检查是否还有足够的数字来完成序列。
public int[] solve(int[] arr) {
if (arr.length % 2 != 0)
return null;
int[] solution = new int[arr.length / 2];
if (solve(arr, 0, 0, solution))
return solution;
return null;
}
private boolean solve(int[] arr, int i, int j, int[] solution) {
if (i == j) {
solution[i] = arr[i + j];
return solve(arr, i + 1, j, solution);
} else if (i == solution.length) {
for (int k = 0; k + i + j < arr.length; k++)
if (arr[k + i + j] != solution[j + k])
return false;
return true;
} else {
for (int k = 0; i + k <= solution.length; k++) {
if (arr[i + j + k] == solution[j] && solve(arr, i + k, j + 1, solution))
return true;
if (i + k < solution.length)
solution[i + k] = arr[i + j + k];
}
return false;
}
}
这只是从左到右检查,而不是从两端检查。其他可能的改进:
它是 Java 代码,但可以很容易地转换为 C++。数组通过引用传递。我测试了一些简单的案例,并且对那些有效的案例进行了测试。
通过内存,我可以在几毫秒内轻松解决多达 50000 个问题。但是我不得不将堆栈大小增加到 100M。您可能希望将其重写为迭代解决方案而不是递归解决方案。
public static int[] solve(int[] arr) {
if (arr.length % 2 != 0)
return null;
int[] solution = new int[arr.length / 2];
if (solve(arr, 0, 0, solution, new Node(null, null)))
return solution;
return null;
}
private static boolean solve(int[] arr, int i, int j, int[] solution, Node node) {
if (node.checked)
return false;
if (i == j) {
if (node.children.containsKey(arr[i + j]))
node = node.children.get(arr[i + j]);
else
node = new Node(node, arr[i + j]);
if (node.checked)
return false;
solution[i] = arr[i + j];
Node n = new Node(node, solution[i]);
if (solve(arr, i + 1, j, solution, n))
return true;
n.checked = true;
return false;
} else if (i == solution.length) {
for (int k = 0; k + i + j < arr.length; k++)
if (arr[k + i + j] != solution[j + k]) {
node.checked = true;
return false;
}
return true;
} else {
Node n = node;
for (int k = 0; i + k <= solution.length; k++) {
if (arr[i + j + k] == solution[j] && solve(arr, i + k, j + 1, solution, n))
return true;
if (i + k < solution.length) {
if (n.children.containsKey(arr[i + j + k]))
n = n.children.get(arr[i + j + k]);
else
n = new Node(n, arr[i + j + k]);
if (n.checked)
return false;
solution[i + k] = arr[i + j + k];
}
}
node.checked = true;
return false;
}
}
private static class Node {
public boolean checked;
public Map<Integer, Node> children = new HashMap<>();
public Node(Node parent, Integer value) {
if (parent != null)
parent.children.put(value, this);
}
}
关于c++ - 检查一个序列是否由两个相同的序列组成,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/69547282/
我正在阅读 Python 文档以真正深入了解 Python 语言,并遇到了 filter 和 map 函数。我以前使用过过滤器,但从未使用过映射,尽管我在 SO 上的各种 Python 问题中都见过这
当我尝试打印 BST 的级别顺序时,这个问题提示了我。 这是一个 Pre-Order Sequence: 4, 1, 2, 3, 5, 6, 7, 8 In_order Sequence : 1, 2
我的代码在 main(序列测试;)的第一行出现错误,指出它是对 sequence::sequence() 的 undefined reference 。我无法更改 main 中的代码。有谁知道我该如何
这可能很简单,但我在通常的 latex 指南中找不到任何相关内容。在这句话中: {\em hello\/} “\/”的目的是什么? 最佳答案 这就是所谓的斜体校正。其目的是确保斜体文本后有适当的间距。
当我从 Postgresql 表中删除所有记录,然后尝试重置序列以在插入时开始一个编号为 1 的新记录时,我得到不同的结果: SELECT setval('tblname_id_seq', (SELE
在版本10.0.3中,MariaDB引入了一种称为序列的存储引擎。 其ad hoc为操作生成整数序列,然后终止。 该序列包含正整数,以降序或升序排列,并使用起始,结束和递增值。 它不允许在多个查询中
如何在 Groovy 中获取给定数字的序列,例如: def number = 169 // need a method in groovy to find the consecutive number
基本上,如果这是 .NET,它看起来像这样: ISomething { string A { get; } int B { get; } } var somethings = new List
说以下代码部分(同一块): A <= 1 A <= 2 变量 A 总是被赋值为 2 吗?还是会出现竞争条件并分配 1 或 2? 我对非阻塞赋值的理解是,由硬件在 future 分配变量 A,因此它可能
在运行 WiX 设置时,我正在寻找操作列表及其顺序。不知何故,官方网站似乎没有提供任何信息。 基本问题是我想正确安排我的自定义操作。通常我需要使用 regsvr32.exe 注册一个 DLL,而这只能
F#初学者在这里 我想创建一个类型,它是具有至少一个元素的另一种具体类型(事件)的序列。任何其他元素都可以在以后随时添加。通常在 C# 中,我会创建一个具有私有(private) List 和公共(p
作为构建过程和不断发展的数据库的一部分,我试图创建一个脚本,该脚本将删除用户的所有表和序列。我不想重新创建用户,因为这将需要比所允许的更多的权限。 我的脚本创建了一个过程来删除表/序列,执行该过程,然
我想恢复两个向量的第一个日期和相同向量的第二个日期之间的日期序列,.... 这是一个例子: dates1 = as.Date(c('2015-10-01', '2015-03-27', '2015-0
这个问题已经有答案了: sql ORDER BY multiple values in specific order? (12 个回答) 已关闭 9 年前。 我有一个 sql 语句,我想要ORDER
我想恢复两个向量的第一个日期和相同向量的第二个日期之间的日期序列,.... 这是一个例子: dates1 = as.Date(c('2015-10-01', '2015-03-27', '2015-0
在用java编写代码时,我需要用“],[”分割字符串。下面是我的代码。 try (BufferedReader reader = new BufferedReader(new InputStreamR
这个问题已经有答案了: Project Euler Question 14 (Collatz Problem) (8 个回答) 已关闭 9 年前。 我正在尝试查找数字的 Collatz 序列。以下
我有一个例程函数process_letter_location(const char& c, string &word)。 在我的 main 中,我声明了一系列字符串变量,如下所示: string s
我需要找到最长的多米诺骨牌链,给定一组 12 个随机挑选的多米诺骨牌。我已经递归地生成了多米诺骨牌的所有可能性(使用 0 到 12 的面值有 91 种可能性)。多米诺骨牌由一 block “砖 blo
我有这个数据结构 Seq,它继承了类 vector 但有一些额外的功能。使用这个数据结构 Seq 我有这个预定义的数据结构: typedef Seq > MxInt2d; 我现在想要一个包含多个 Mx
我是一名优秀的程序员,十分优秀!