检查是否可以从指定的数字序列创建算术序列的最有效方法是什么?
目前我对序列进行排序,然后执行此操作:
#include<bits/stdc++.h>
using namespace std;
static bool sort_using_greater_than(float u, float v)
{
return u > v;
}
int main()
{
int licznik=0, i=0;
double number[100000];
while(~scanf("%f", &number[i]))
{
i++;
licznik++;
}
sort(number,number+100, sort_using_greater_than);
for(int i = 1; i < licznik-1; i++)
{
if(number[i] - number[i+1] != number[0] - number[1])
{
puts("NO");
return 0;
}
}
puts("YES");
}
进行测试:
我的代码返回YES,为什么?
enter code here
double search_min(double tab[], int n)
{
double min = tab[0];
for(int i = 1; i < n; i++)
{
if(min > tab[i])
min = tab[i];
return min;
}
而且,我怎样才能找到两个最小的元素?
答案 0 :(得分:3)
问题尚不清楚,但如果它意味着“检查给定的数字是否可以从一个算术序列重新排列”,那么就没有必要进行排序。
找到最小的元素,在O(N)中,让a;
找到第二个最小的,在O(N)中,让b;
清除O(N)中的N位数组;
对于每个数字c,计算(c - a)/(b - a);如果这不是范围[0,n-1]中的整数,则答案为否。否则,将该位设置为该索引(在每个元素的O(1)中完成);
检查所有位是否已在O(N)中设置。
整个过程需要时间O(N)。
答案 1 :(得分:-1)
O(n)是您必须检查每个元素的最佳选择。
我已经实现了Yves Daoust的算法(有一些小的优化)以及你自己的C ++ 14标准代码。
这是你的:
int main(int argc, char* argv[]) {
if(argc == 1) return 0;
//Copy command args to vector of strings.
std::size_t number_count = argc - 1;
std::vector<std::string> cmd_args(number_count);
std::copy(argv + 1, argv + argc, cmd_args.begin());
//Copy convert vector of strings to vector of ints.
std::vector<int> values(number_count);
auto v_begin = values.begin();
for(auto s : cmd_args) {
(*v_begin) = std::stoi(s);
++v_begin;
}
//Sort values in ascending order.
std::sort(values.begin(), values.end());
//Get smallest two values.
std::pair<int, int> two_smallest_values(*values.cbegin(), *(values.cbegin() + 1));
//Calculate differences between each successive number
std::vector<int> differences(values.size() - 1);
for(std::size_t i = 0; i < values.size() - 1; ++i) {
differences[i] = std::abs(values[i] - values[i + 1]);
}
//All values in differences must be the same.
if(std::all_of(differences.cbegin(), differences.cend(), [=](int i) { return i == *differences.cbegin(); })) {
std::cout << "YES\n";
} else {
std::cout << "NO\n";
}
return 0;
}
这是Yves Daoust的算法:
int main(int argc, char* argv[]) {
if(argc == 1) return 0;
//Copy command args to vector of strings.
std::size_t number_count = argc - 1;
std::vector<std::string> cmd_args(number_count);
std::copy(argv + 1, argv + argc, cmd_args.begin());
//Copy convert vector of strings to vector of ints.
auto v_begin = values.begin();
for(auto s : cmd_args) {
(*v_begin) = std::stoi(s);
++v_begin;
}
//Sort values in ascending order.
std::sort(values.begin(), values.end());
//Get smallest two values.
std::pair<int, int> two_smallest_values(*values.cbegin(), *(values.cbegin() + 1));
std::vector<bool> bits(values.size());
bool result = true;
int smallest_diff = (two_smallest_values.second - two_smallest_values.first);
for(auto v : values) {
int numerator = v - two_smallest_values.first;
int denominator = smallest_diff;
if(numerator % denominator != 0) {
result = false;
break;
}
std::size_t i = numerator / denominator;
if(i < 0 || i >= values.size()) {
result = false;
break;
}
bits[i] = true;
}
if(result == false) {
std::cout << "NO\n";
return 0;
}
//Convert vector of bools (bit-packed) to an unsigned int.
unsigned long long bits_value = 0;
unsigned long long i = 0;
for(auto b : bits) {
bits_value |= (b << i++);
}
//Optimization: Single calculation to determine if all bits are set:
if(std::abs(bits_value - (std::pow(2.0, bits.size()) - 1) < 0.01)) {
std::cout << "YES\n";
} else {
std::cout << "NO\n";
}
return 0;
}