我解决了这个问题陈述(耶耶,我知道,我正在把问题陈述放在下面)。
给出了一个整数X和一个长度为n的整数序列:p1,…,pn。 在序列p1,…,pN中不包含的整数中(不一定是正的),求出离X最近的整数,即与X的绝对差值最小的整数。 如果有多个这样的整数,报告最小的这样的整数
这是我使用的代码:
#include <algorithm>
#include <cstdlib>
#include <iostream>
#include <numeric>
#include <vector>
int main() {
int x = 0;
int n = 0;
std::cin >> x >> n;
std::vector<decltype(x)> vect(n);
bool vect_contains_x = false;
for (auto& elem : vect) {
std::cin >> elem;
if (elem == x) {
vect_contains_x = true;
}
}
int num = 0;
if (!vect_contains_x) {
num = x;
}
else {
std::sort(vect.begin(), vect.end());
while (1) {
static int i = 1;
if (std::find(vect.begin(), vect.end(), x - i) == vect.end()) {
num = x - i;
break;
}
else if (std::find(vect.begin(), vect.end(), x + i) == vect.end()) {
num = x + i;
break;
}
else {
i += 1;
}
}
}
std::cout << num << "\n";
return 0;
}
此代码在13-18ms
中呈现结果。
通过使用以下优化代码,我能够将其降至8-10ms
:
#include <algorithm>
#include <cstdlib>
#include <iostream>
#include <numeric>
#include <vector>
int main() {
int x = 0;
int n = 0;
std::cin >> x >> n;
std::vector<decltype(x)> vect(n);
bool vect_contains_x = false;
for (auto& elem : vect) {
std::cin >> elem;
if (elem == x) {
vect_contains_x = true;
}
}
int num = 0;
if (!vect_contains_x) {
num = x;
}
else {
std::sort(vect.begin(), vect.end());
auto isPresent = [=](auto num) {
for (const auto& elem : vect) {
if (num == elem) {
return true;
}
}
return false;
};
while (1) {
static int i = 1;
if (!isPresent(x - i)) {
num = x - i;
break;
}
else if (!isPresent(x + i)) {
num = x + i;
break;
}
else {
i += 1;
}
}
}
std::cout << num << "\n";
return 0;
}
但是,这两种代码的问题(因为它们都使用相同的方法)在于,如果给定列表中存在大量连续的整数流,则如下所示:
1,2,3,4,5,6,7,8,9,10,。。。,1501
给出的X是
751
代码将需要对for loop
进行750次迭代,这是非常多的。 我们能不能用更好的算法找到最接近的整数?
编辑:
通过使用binary_search
(谢谢@Sebastian)将其降至6ms
,但算法仍然保持不变。。。
根据你的链接,整数的总数最多是100。 因此,100位足以保存标志,这些数字出现在序列中。 它们可以保存在处理器寄存器中。
下面的代码只显示了存储空间,后面您必须选择合适的位扫描操作:
#include <cstdlib>
#include <iostream>
#include <numeric>
#include <limits>
#include <bitset>
using namespace std;
int main() {
bitset<100> flags;
int x = 0;
int n = 0;
int min = std::numeric_limits<int>::max();
int num = 0;
std::cin >> x >> n;
for (int i = 0; i < n; i++) {
int elem;
std::cin >> elem;
flags.set(elem);
}
// then you can shift the result by x bits and do bit scan operations
// there are built-ins depending on the compiler and processor architecture or the portable De Bruijn with multiplications
}
// alternatively (to the shift) you can use two bitsets, and for one set all the elements (elem - x) or for the other (x - elem)
这是我的O(N)的代码,我的代码需要6ms来求解。
#include <bits/stdc++.h>
using namespace std;
#define FastIO ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
const int inf = 1e9;
int is_find[200];
int main()
{
FastIO
int value, x, n;
cin >> x >> n;
for(int i = 0; i < n; i++)
{
cin >> value;
is_find[ value ] = 1;
}
int ans = -1, mn = inf;
for(int i = 0; i <= 101; i++)
{
if(is_find[i] == 0){
if(mn > abs(i - x)){
mn = abs(i - x);
ans = i;
}
}
}
cout << ans << endl;
return 0;
}
///Before submit=>
/// *check for integer overflow,array bounds
/// *check for n=1