上链接:Problem - B - Codeforceshttps://codeforces.com/contest/1656/problem/B
题目分析:
1.本菜菜一开始想到的居然是DFS,完全跑偏(因为这个回溯,删除都是非常难操作的)。
2.观察数据你会发现给定数组能够所剩下一个元素的值k,只要原数组里有两个数的差=k即可,然后本菜菜就想着用for循环写:
#include <iostream>
#include <algorithm>
#include <cmath>
using namespace std;
int t;
long long n, m;
long long a[250000];
int main()
{
int t;
cin >> t;
while (t--) {
int flag = 0;
cin >> n >> m;
for (int i = 1; i <= n; i++) {
cin >> a[i];
}
sort(a + 1, a + n + 1);
for (int i = 1; i <n; i++) {
for (int j = i + 1; j <= n; j++) {
if (abs(a[i] - a[j]) == m) {
flag = 1;
break;
}
if (abs(a[i] - a[j]) > m) {
break;
}
}
}
if (flag == 1) {
cout << "YES" << endl;
}
else {
cout << "NO" << endl;
}
}
}
尽管本菜菜想了许多方法来优化算法,也依然是O(n^2),还是超时了,因为该题数据很大,所以很惨烈的阵亡了,用数组标记的方法,你不能让我的vis数组开到(-10^9--10^9)吧,于是查资料有了新的方法,直接降到了O(n),利用map映射函数进行标记:
#include<iostream>
#include<map>
using namespace std;
const int N = 2e5 + 8;//养成一个好习惯
int n, k;
int a[N];
map<int, bool> mp;
void solve()
{
mp.clear();//清空
cin >> n >> k;
for (int i = 1; i <= n; i++) {
cin >> a[i];
}
for (int i = 1; i <= n; i++) {
mp[a[i]] = 1;//将数组所有的数全部标记好
}
for (int i = 1; i<=n; i++) {
if (mp[a[i] + k]) {//该数不存在,键值=0,存在键值=1
cout << "YES" << endl;
return;
}
}
cout << "NO" << endl;
}
int main()
{
int t = 1;
cin >> t;
while (t--) {
solve();
}
}
那今天的总结就先到这里,累了,睁不开眼了,明天见,感谢观看!