Where is the Pizza?
有a,b,d三个数组问能构造多少个c数组
- 若则
- a,b,c均为1~n的排列
1~n的排列说明c中的每个数都只能出现一次,那么对于每个位置只能选一个,且若此为位置选定后,那么另一个位置也是确定的对于ai与bi不相等的情况,每个位置有两个选择。由于d[i[的影响,d[i]!=0那么c[i]就是确定的。我们可以对ai和bi构造一个无向边,以此来确定每次的选择。
#include <bits/stdc++.h>
typedef long long LL;
const int P = 1e9 + 7;
const int N = 1e5 + 9;
void solve() {
int n;
std::cin >> n;
std::vector<int>a(n + 1), b(n + 1), d(n + 1), p(n + 1);
for (int i = 1; i <= n; i++) {
std::cin >> a[i];
}
for (int i = 1; i <= n; i++) {
std::cin >> b[i];
}
for (int i = 1; i <= n; i++) {
std::cin >> d[i];
}
std::iota(p.begin() + 1, p.end(), 1);
std::function<int(int)> find = [&](int x) {
if (x != p[x]) {
x = find(p[x]);
}
return p[x];
};
LL ans = 1;
for (int i = 1; i <= n; i++) {
if (d[i] || a[i] == b[i]) {
continue;
}
int x = find(a[i]), y = find(b[i]);
if (x != y) {
p[x] = y;
} else {
ans = (ans * 2) % P;
}
}
std::cout << ans % P << "\n";
}
int main() {
std::ios::sync_with_stdio(false);
std::cin.tie(nullptr);
int t;
std::cin >> t;
while (t--) {
solve();
}
return 0;
}
Very Suspicious
根据题意可知共有三个不同斜率的直线,每两个不同斜率的直线会有一个交点并构造出两个等边三角形,那么我们为最大限度的获得等边三角形,设总共有x条直线,每种斜率的直线以x/3分配,余下的我们随便分配给两条直线即可,那么怎么通过直线个数来算有多少个等边直角三角形呢,我们知道一个交点会有两个等边三角形生成,所以只需要算交点个数后*2即可,交点个数通过画图可知就是两条线个数相乘得到。最后选择二分查找来搜索答案。
#include <bits/stdc++.h>
typedef long long LL;
int n, a, b, c;
bool judge(int x) {
a = b = c = x / 3;
if (x % 3 >= 1) {
a++;
}
if (x % 3 >= 2) {
b++;
}
return 2LL * (a * b + b * c + c * a) >= n;
}
void solve() {
std::cin >> n;
int l = 1, r = 1e5;
while (l < r) {
int mid = (l + r) >> 1;
if (judge(mid)) {
r = mid;
} else {
l = mid + 1;
}
}
std::cout << r << "\n";
}
int main() {
std::ios::sync_with_stdio(false);
std::cin.tie(nullptr);
int t;
std::cin >> t;
while (t--) {
solve();
}
return 0;
}