HAUT2021蓝桥杯专题练习第二周记录——搜索
这周因为迷迷糊糊的早早的写完了,然后玩了好几天基本上题都忘完了才写的博客,基本上啥都不记得了QAQ
说迷迷糊糊是因为这周确实太懵了,精度问题,还有我原本就不太会的前缀和,然后力扣这个月又是滑窗月,每日都很头疼。
不过,总算是跟着题解做完了
题目列表
- HAUT2021蓝桥杯专题练习第二周记录——搜索
-
- A 二分查找(一)(计蒜客T1560)
- B 二分查找(三)(计蒜客T1562)
- C 二分查找(六)(计蒜客T1556)
- D 和为给定数(计蒜客T1158)
- E 一元三次方程求解(NOIP2001 提高组)
- F 切绳子(P1577)
- G 砍树(P1873)
- H Pie(UVA12097)
- I Monthly Expense(P2884)
- J Can you solve this equation?(HDU2199)
- K Magic Ship(CF1117C )
- L Stressful Training(CF1132D)
- M 前缀极差(计蒜客T3094)
- N Segment Occurrences(CF1016B)
- O Number of Ways(CF466C)
- P String(HDU5672)
- Q Subsequence(UVA1121)
- R Bound Found(POJ2566)
- S Unique Snowflakes(UVA11572 )
- 总结
A 二分查找(一)(计蒜客T1560)
前面三道题基本上差不多,本意不知道是不是让自己写个模板的,我是用的C++里面的二分查找函数直接写的。(让我自己写我也不会,毕竟我这么菜
AC代码
#include <bits/stdc++.h>
using namespace std;
const int max_n = 100100;
int arr[max_n];
int main()
{
int n, m;
cin >> n >> m;
for (int i = 0; i < n; i++)
cin >> arr[i];
sort(arr, arr + n);
while (m--)
{
int tmp;
cin >> tmp;
if (!binary_search(arr, arr + n, tmp))
cout << "NO" << endl;
else
cout << "YES" << endl;
}
return 0;
}
B 二分查找(三)(计蒜客T1562)
和A差不多,直接上代码了。
AC代码
#include <bits/stdc++.h>
using namespace std;
const int max_n = 100100;
int arr[max_n];
int main()
{
int n, m;
cin >> n >> m;
for (int i = 0; i < n; i++)
cin >> arr[i];
sort(arr, arr + n);
while (m--)
{
int tmp;
cin >> tmp;
int *res = upper_bound(arr, arr + n, tmp);
if (res != &arr[n])
cout << *res << endl;
else
cout << "-1" << endl;
}
return 0;
}
C 二分查找(六)(计蒜客T1556)
同上。如果不明白这三个函数到时候再查查就行了。
AC代码
#include <bits/stdc++.h>
using namespace std;
const int max_n = 100100;
int arr[max_n];
int main()
{
int n, m;
cin >> n >> m;
for (int i = 0; i < n; i++)
cin >> arr[i];
sort(arr, arr + n);
while (m--)
{
int tmp;
cin >> tmp;
int *res = lower_bound(arr, arr + n, tmp) - 1;
if (res == &arr[0] - 1)
cout << "-1" << endl;
else
cout << *res << endl;
}
return 0;
}
D 和为给定数(计蒜客T1158)
遍历一个数,然后二分查找另一个数,成立直接输出答案就行了。
AC代码
#include <bits/stdc++.h>
using namespace std;
const int max_n = 100100;
int arr[max_n];
int main()
{
int n, m;
cin >> n;
for (int i = 0; i < n; i++)
cin >> arr[i];
cin >> m;
sort(arr, arr + n);
for (int i = 0; i < n - 1; i++)
{
int res1 = arr[i];
int *res2 = lower_bound(arr + i + 1, arr + n, m - res1);
if (res1 + *res2 == m)
{
cout << res1 << " " << *res2 << endl;
return 0;
}
}
cout << "No" << endl;
return 0;
}
E 一元三次方程求解(NOIP2001 提高组)
暴力出奇迹,直接暴力解法,枚举所有解。
AC代码
#include <bits/stdc++.h>
using namespace std;
double a, b, c, d;
int main()
{
cin >> a >> b >> c >> d;
for (double x = -100; x <= 100; x += 0.01)
{
if (abs(a * x * x * x + b * x * x + c * x + d) <= 1e-5)
{
printf("%.2f ", x);
}
}
cout << endl;
return 0;
}
F 切绳子(P1577)
精度问题,下面好几道都是这种题,让我头疼的要死当时……
这道题可以先把数乘100,在最后再除下去就行了。本身也就是模板题那种吧,感觉也不难。
AC代码
#include <bits/stdc++.h>
using namespace std;
const int max_n = 10010;
double arr[max_n];
int n, m;
bool cal(int x)
{
int sum = 0;
for (int i = 0; i < n; i++)
sum += arr[i] / x;
return sum >= m;
}
int main()
{
cin >> n >> m;
for (int i = 0; i < n; i++)
{
cin >> arr[i];
arr[i] *= 100;
}
int left = 0, right = 1 << 30;
while (left <= right)
{
int mid = (left + right) / 2;
if (mid == 0)
break;
if (cal(mid))
left = mid + 1;
else
right = mid - 1;
}
printf("%.2lf\n", (right + left) / 2 * 1.0 / 100);
return 0;
}
G 砍树(P1873)
标准二分,不用注意精度直接无脑上就行了。注意用long long。
AC代码
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;