一、AcWing 3971. 最小的商
题目链接:AcWing 3971. 最小的商
思路:排序
对数组进行降序排序,找到第一个能够用k整除
a
i
a_i
ai的数字即可。
时间复杂度: O ( n l o g n ) O(nlogn) O(nlogn)
代码(C++)
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 110;
int q[N];
int main()
{
int T;
cin >> T;
while (T -- )
{
int n, k;
cin >> n >> k;
memset(q, 0,sizeof q);
for (int i = 0; i < n; i ++ ) cin >> q[i];
sort(q, q + n, greater<int>());
//for (int i = 0; i < n; i ++ ) cout << q[i] << ' ';
for (int i = 0; i < n; i ++ )
if (k % q[i] == 0)
{
cout << k / q[i] << endl;
break;
}
}
return 0;
}
二、AcWing 3972. 方格集数量
题目链接:AcWing 3972. 方格集数量
思路:模拟
∵
\because
∵
(
1
+
1
)
n
=
C
n
0
+
C
n
1
+
C
n
2
+
C
n
3
+
…
+
C
n
n
=
2
n
(1 + 1)^{n} = C_n^{0} +C_n^{1}+C_n^{2}+C_n^{3}+\ldots+C_n^{n} = 2^n
(1+1)n=Cn0+Cn1+Cn2+Cn3+…+Cnn=2n
∴
\therefore
∴
C
n
1
+
C
n
2
+
C
n
3
+
⋅
⋅
⋅
⋅
+
C
n
n
=
2
n
−
1
C_n^{1}+C_n^{2}+C_n^{3}+···· +C_n^{n} = 2^n - 1
Cn1+Cn2+Cn3+⋅⋅⋅⋅+Cnn=2n−1
但是,对于集合中仅含一个方格的情况,该方格会被所在行计算一次,所在列计算一次,所以实际上计算了两次。也即,矩阵中每个方格都被额外计算了一次,所以最后的结果要减去所有方格数。
时间复杂度: O ( n m ) O(nm) O(nm)
代码(C++)
#include <iostream>
using namespace std;
typedef long long LL;
const int N = 55;
int n, m;
int rows[N], cols[N];
int main()
{
cin >> n >> m;
for (int i = 0; i < n; i ++ )
for (int j = 0; j < m; j ++ )
{
int c;
cin >> c;
if (c) rows[i] ++, cols[j] ++;
}
LL res = 0;
for (int i = 0; i < n; i ++ )
{
res += (1ll << rows[i]) - 1;
res += (1ll << m - rows[i]) - 1;
}
for (int i = 0; i < m; i ++ )
{
res += (1ll << cols[i]) - 1;
res += (1ll << n - cols[i]) - 1;
}
cout << res - n * m << endl;
return 0;
}
三、AcWing 3973. 无线网络
题目链接:AcWing 3973. 无线网络
思路:双指针、二分
时间复杂度: O ( n l o g n ) O(nlogn) O(nlogn)
代码(C++)
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
typedef long long LL;
const int N = 100010;
int n, m;
int a[N], b[N]; //站点 和 基站
bool check(int r)
{
for (int i = 0, j = 0; i < n; i ++ )
{
while (j + 1 < m && b[j + 1] <= a[i]) j ++;
if (abs(a[i] - b[j]) > r)
{
if (j + 1 >= m || abs(a[i] - b[j + 1]) > r) //不存在任何一个可以覆盖
return false;
}
}
return true;
}
int main()
{
scanf("%d%d",&n, &m);
for (int i = 0; i < n; i ++ ) scanf("%d", &a[i]);
for (int i = 0; i < m; i ++ ) scanf("%d", &b[i]);
int l = 0, r = 2e9;
while (l < r)
{
int mid = (LL)l + r >> 1;
if (check(mid)) r = mid;
else l = mid + 1;
}
printf("%d\n", r);
return 0;
}