雨还下个不停,就在实验室打打题,活动活动脑子。
\
山东省第八届ACM程序设计竞赛。国庆节重现赛。
A题是威佐夫博弈+Nim游戏博弈论。若了解这两个博弈游戏的话,超级简单的一道题。
C题烟火爆炸,难在求组合数,需要用到逆元。其中我代码中的求法可以提取出来当板子用。
F题判段离散数学中的一个条件命题是否正确。难点是判断浮点数a / b是否为整数。iff a % b = 0
G题快速幂
I题同余定理,边乘边取余。
J题数组展开,弄个后缀和。贪心一下,1A哈
K题01背包。先做扣分快,容易做的题。两者综合考虑。
\
下面是代码。写得很粗糙。。。
A题 (威佐夫博弈百度百科)
#include <cstdio>
#include <cmath>
#include <algorithm>
using namespace std;
//#define TEST
int main()
{
#ifdef TEST
freopen("data.in", "r", stdin);
freopen("data.out", "w", stdout);
#endif
//ios::sync_with_stdio(false);
int T;
scanf("%d", &T);
while(T-- > 0) {
int n;
scanf("%d", &n);
int a[50];
for (int i = 0; i < n; ++i) {
scanf("%d", a + i);
}
if(n == 2) {
if(a[0] > a[1]) {
swap(a[0], a[1]);
}
if(floor((a[1]-a[0]) * ((sqrt(5.0)+1.0)/2.0) ) != a[0]){
printf("Sherlock\n");
}
else {
puts("Watson");
}
}
else {
int k = 0;
for (int i= 0; i < n; ++i) {
k ^= a[i];
}
if(k == 0) {
puts("Watson");
}
else {
puts("Sherlock");
}
}
}
return 0;
}
\
C题
#include <cstdio>
const int mod = 1e9 + 7;
typedef long long LL;
const int N = 1e5 + 7;
LL fac[N];
void factor() {
fac[0] = fac[1] = 1;
for (int i= 2; i < N; ++i) {
fac[i] = fac[i - 1] * i % mod;
}
}
LL quick_pow(LL a, LL n) {
LL res = 1;
while(n > 0) {
if(n & 1) res = res * a % mod;
a = a * a % mod;
n >>= 1;
}
return res;
}
LL C(LL n, LL m) {
return fac[n] * quick_pow(fac[n - m], mod - 2) % mod
* quick_pow(fac[m], mod - 2) % mod;
}
int main()
{
factor();
int n, t, w;
while(~scanf("%d%d%d", &n, &t, &w)) {
LL res = 0;
for (int i = 0; i < n; ++i) {
LL x, val;
scanf("%lld%lld", &x, &val);
LL k = w - x >= 0 ? w - x : x - w;
if((k & 1) == (t & 1) && k <= t) //距离 时间 同奇共偶。且距离小于时间 * 1
res = (res + (val * C(t, (k + t) >> 1)) % mod) % mod;
}
printf("%lld\n", res);
}
return 0;
}
F题
#define _CRT_SECURE_NO_WARNINGS
#include <cstdio>
#include <iostream>
#include <iomanip>
#include <cstring>
#include <string>
#include <algorithm>
#include <climits>
#include <cmath>
#include <vector>
#include <set>
#include <map>
#include <queue>
#include <stack>
#include <ctime>
#include <cstdlib>
#include <iterator>
using namespace std;
const double eps = 1e-8;
//#define TEST
int main()
{
#ifdef TEST
freopen("data.in", "r", stdin);
freopen("data2.out", "w", stdout);
#endif
//ios::sync_with_stdio(false);
int T;
scanf("%d", &T);
while(T-- > 0) {
int a, b, c;
scanf("%d%d%d", &a, &b, &c);
if(a == 0) {
if(b == 0) {
if(c != 0) puts("YES"); //if不成立
else puts("NO"); //x可能不是int
}
else {//有一个解
if(c % b == 0) puts("YES"); //假设成立
else puts("NO"); //不成立
}
continue;
}
double delta = b * b - 4 * a * c;
if(delta < 0) { //二次方程,无解。if不成立
puts("YES");
continue;
}
int tmp = sqrt(delta);
delta = sqrt(delta);
//printf("delta = %lf\n", delta);
double x1 = (-b + delta) / (2.0 * a);
double x2 = (-b - delta) / (2.0 * a);
//printf("x1 = %d, x2 = %d\n", x1, x2);
if(delta - tmp < eps &&//浮点数相等
(-b + tmp) % (2 * a) == 0 &&
(-b - tmp) % (2 * a) == 0) {
puts("YES");
}
else puts("NO");
}
return 0;
}
G题
#define _CRT_SECURE_NO_WARNINGS
#include <cstdio>
#include <iostream>
#include <iomanip>
#include <cstring>
#include <string>
#include <algorithm>
#include <climits>
#include <cmath>
#include <vector>
#include <set>
#include <map>
#include <queue>
#include <stack>
#include <ctime>
#include <cstdlib>
#include <iterator>
using namespace std;
const int mod = 1e9 + 7;
long long pow_mod(long long b, long long n) {
long long res = 1;
while(n) {
if(n & 1) res = (res * b) % mod;
b = b * b % mod;
n >>= 1;
}
return res;
}
//#define TEST
int main()
{
#ifdef TEST
freopen("data.in", "r", stdin);
freopen("data.out", "w", stdout);
#endif
//ios::sync_with_stdio(false);
long long n, m;
while(~scanf("%lld%lld", &n, &m)) {
long long res = 0;
for (long long i = 1; i <= n; ++i) {
res = (res + pow_mod(i, m)) % mod;
}
printf("%lld\n", res);
}
return 0;
}
I题
#define _CRT_SECURE_NO_WARNINGS
#include <cstdio>
#include <iostream>
#include <iomanip>
#include <cstring>
#include <string>
#include <algorithm>
#include <climits>
#include <cmath>
#include <vector>
#include <set>
#include <map>
#include <queue>
#include <stack>
#include <ctime>
#include <cstdlib>
#include <iterator>
using namespace std;
const int N = 1007;
char str[N];
//#define TEST
int main()
{
#ifdef TEST
freopen("data.in", "r", stdin);
freopen("data.out", "w", stdout);
#endif
//ios::sync_with_stdio(false);
while(~scanf("%s", str)) {
int len = strlen(str);
int res = 0;
for (int i = 0; i < len; ++i) {
res = (res * 10 + str[i] - '0') % 3;
}
if(res == 0) puts("0");
else puts("1");
}
return 0;
}
J题
#define _CRT_SECURE_NO_WARNINGS
#include <cstdio>
#include <iostream>
#include <iomanip>
#include <cstring>
#include <string>
#include <algorithm>
#include <climits>
#include <cmath>
#include <vector>
#include <set>
#include <map>
#include <queue>
#include <stack>
#include <ctime>
#include <cstdlib>
#include <iterator>
using namespace std;
const int N = 100007;
int st[N];
long long suf[N];
struct Node {
int val, cnt;
bool operator < (const Node &tmp) const {
return val < tmp.val;
}
}a[1007];
//#define TEST
int main()
{
#ifdef TEST
freopen("data.in", "r", stdin);
freopen("data.out", "w", stdout);
#endif
//ios::sync_with_stdio(false);
int n;
while (~scanf("%d", &n)) {
for (int i = 0; i < n; ++i) scanf("%d", &a[i].val);
for (int i = 0; i < n; ++i) scanf("%d", &a[i].cnt);
sort(a, a + n);
int cur = 0;
for (int i = 0; i < n; ++i) {
while (a[i].cnt-- > 0) st[cur++] = a[i].val;
}
suf[cur] = 0;
int start = 0;
for (int i = cur - 1; i >= 0; --i) {
suf[i] = st[i] + suf[i + 1];//后缀
if (suf[i] <= 0) {
start = i + 1;
break;
}
}
//printf("start = %d\n", start);
long long res = 0;
for (int i = start, j = 1; i < cur; ++i, ++j) {
res += j * st[i];
}
printf("%lld\n", res);
}
return 0;
}
K题
#include <cstdio>
#include <iostream>
#include <iomanip>
#include <cstring>
#include <string>
#include <algorithm>
#include <climits>
#include <cmath>
#include <vector>
#include <set>
#include <map>
#include <queue>
#include <stack>
#include <ctime>
#include <cstdlib>
#include <iterator>
using namespace std;
const int N = 2007;
struct ABCD {
int a, c, d;
double v; //正比于时间c,反比于降率d
bool operator < (const ABCD& tmp) const {
return v < tmp.v; //起初忘了写return
}
}t[N];
int dp[5007];
int main()
{
int n, T;
while(~scanf("%d%d", &n, &T)) {
for (int i = 0; i < n; ++i) scanf("%d", &(t[i].a));
for (int i = 0; i < n; ++i) scanf("%d", &(t[i].d));
for (int i = 0; i < n; ++i) {
scanf("%d", &(t[i].c));
t[i].v = t[i].c / (double)t[i].d;
}
sort(t, t + n);
memset(dp, 0, sizeof dp); //dp[time] = grade
int maxV = 0;
for (int i = 0; i < n; ++i) {
for (int j = T; j >= t[i].c; --j) {
dp[j] = max(dp[j], dp[j - t[i].c] + t[i].a - t[i].d * j);
maxV = max(maxV, dp[j]);
}
}
printf("%d\n", maxV);
}
return 0;
}
\
\