Problem A. ABCD
题目大意
给出一个四边形四条边 AB、CD、AD、BC 及两条对角线 AC、BD 的长度,问这个四边形的顶点能否在一个圆上
算法思路
通过余弦定理考察 ∠ACB 与 ∠ADB 是否相等即可。
时间复杂度: O(1)
代码
/**
* Copyright © 2016 Authors. All rights reserved.
*
* FileName: A.cpp
* Author: Beiyu Li <sysulby@gmail.com>
* Date: 2016-05-09
*/
#include <bits/stdc++.h>
using namespace std;
#define rep(i,n) for (int i = 0; i < (n); ++i)
#define For(i,s,t) for (int i = (s); i <= (t); ++i)
#define foreach(i,c) for (__typeof(c.begin()) i = c.begin(); i != c.end(); ++i)
typedef long long LL;
typedef pair<int, int> Pii;
const int inf = 0x3f3f3f3f;
const LL infLL = 0x3f3f3f3f3f3f3f3fLL;
const double eps = 1e-10;
int sgn(double x) { return x < -eps? -1: x > eps; }
inline double cosf(double a, double b, double c)
{ return (a * a + b * b - c * c) / (2 * a * b); }
int main()
{
int T, cas = 0;
scanf("%d", &T);
while (T--) {
int ab, cd, ad, bc, ac, bd;
scanf("%d%d%d%d%d%d", &ab, &cd, &ad, &bc, &ac, &bd);
printf("Case #%d: %s\n", ++cas, !sgn(cosf(ac, bc, ab)
- cosf(ad, bd, ab))? "Yes": "No");
}
return 0;
}
Problem B. Bob’s magical number
题目大意
构造一个 N 个点,每个点度数都为3的无向图
算法思路
由于共有 3N2 条边,故 N 为奇数时一定无解
时间复杂度: O(N)
代码
/**
* Copyright © 2016 Authors. All rights reserved.
*
* FileName: B.cpp
* Author: Beiyu Li <sysulby@gmail.com>
* Date: 2016-05-09
*/
#include <bits/stdc++.h>
using namespace std;
#define rep(i,n) for (int i = 0; i < (n); ++i)
#define For(i,s,t) for (int i = (s); i <= (t); ++i)
#define foreach(i,c) for (__typeof(c.begin()) i = c.begin(); i != c.end(); ++i)
typedef long long LL;
typedef pair<int, int> Pii;
const int inf = 0x3f3f3f3f;
const LL infLL = 0x3f3f3f3f3f3f3f3fLL;
int main()
{
int T, cas = 0;
scanf("%d", &T);
while (T--) {
int n;
scanf("%d", &n);
if (n < 4 || (n & 1)) {
printf("Case #%d: No\n", ++cas);
} else {
printf("Case #%d: Yes\n", ++cas);
For(i,1,n) {
printf("%d %d\n", i, i == n? 1: i + 1);
if (i <= n / 2) printf("%d %d\n", i, i + n / 2);
}
}
}
return 0;
}
Problem C. Color
题目大意
用K种颜色对长度为N的环涂色,问考虑旋转同构下本质不同的涂色方案有多少种
算法思路
由Pólya定理可知,答案等于 ∑i=1Nkgcd(i,N)
对于 d=gcd(i,N) , kd 项共有 φ(Nd) 个
所以上式化简为 ∑d|Nφ(Nd)kd
时间复杂度: O(N‾‾√)
代码
/**
* Copyright © 2016 Authors. All rights reserved.
*
* FileName: C.cpp
* Author: Beiyu Li <sysulby@gmail.com>
* Date: 2016-05-09
*/
#include <bits/stdc++.h>
using namespace std;
#define rep(i,n) for (int i = 0; i < (n); ++i)
#define For(i,s,t) for (int i = (s); i <= (t); ++i)
#define foreach(i,c) for (__typeof(c.begin()) i = c.begin(); i != c.end(); ++i)
typedef long long LL;
typedef pair<int, int> Pii;
const int inf = 0x3f3f3f3f;
const LL infLL = 0x3f3f3f3f3f3f3f3fLL;
const int mod = 1000000007;
int n, k, ret;
vector<Pii> fct;
int pow_mod(int a, int b)
{
int ret = 1;
for (; b; a = (LL)a * a % mod, b >>= 1)
if (b & 1) ret = (LL)ret * a % mod;
return ret;
}
void decomp(int n)
{
fct.clear();
for (int i = 2; i * i <= n; ++i) if (n % i == 0) {
fct.push_back(Pii(i, 0));
while (n % i) ++fct.back().second, n /= i;
}
if (n > 1) fct.push_back(Pii(n, 1));
}
void dfs(int i, int gcd, int phi)
{
if (i == fct.size()) {
ret = (ret + (LL)pow_mod(k, gcd) * phi) % mod;
return;
}
dfs(i + 1, gcd, phi);
phi *= fct[i].first - 1;
rep(j,fct[i].second) {
gcd /= fct[i].first;
dfs(i + 1, gcd, phi);
phi *= fct[i].first;
}
}
int main()
{
int T, cas = 0;
scanf("%d", &T);
while (T--) {
scanf("%d%d", &n, &k);
decomp(n);
ret = 0;
dfs(0, n, 1);
ret = (LL)ret * pow_mod(n, mod - 2) % mod;
printf("Case #%d: %d\n", ++cas, ret);
}
return 0;
}
Problem D. Dilettante
题目大意
问用 1×1×1×2 的四维块在可以旋转的情况下填充 2×2×4×n 四维空间的方案数,答案取模 1000000007
算法思路
将最后一维当作时间考虑可以发现,在某一时刻,前三维构成 2×2×4 的 0/1 状态立方体
对于每次转移,要么将两个相邻的0置1,要么将状态取反后到达下一时刻
我们可以先预处理构成某个状态的方案数 f[S]
对于第一种转移, S→T 的转移系数为 f[T−S]
考虑相邻时刻的转移, S→T 的转移系数为 f[T′−S] ,其中