套题链接:http://acm.hust.edu.cn/vjudge/contest/view.action?cid=104302#overview
难度类型:比较基础,除了A需要知道较为偏门的知识,E需要使用并查集。
A
题解
类型:威佐夫博奕
理论上这个算是最难的,因为比较偏门,但是只要接触过的话套个模板上去即可。
#include <iostream>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <cstring>
#include <stack>
#include <queue>
#include <string>
#include <vector>
#include <set>
#include <map>
#define pb push_back
#define mp make_pair
#define all(x) (x).begin(),(x).end()
#define sz(x) ((int)(x).size())
#define fi first
#define se second
using namespace std;
typedef long long LL;
typedef vector<int> VI;
typedef pair<int,int> PII;
LL powmod(LL a,LL b, LL MOD) {LL res=1;a%=MOD;for(;b;b>>=1){if(b&1)res=res*a%MOD;a=a*a%MOD;}return res;}
// head
double phi = (1+sqrt(5))/2.0;
int main()
{
int n, m;
while (scanf("%d%d", &n, &m) == 2) {
int x = phi*abs(n-m);
puts(min(n, m) == x ? "0" : "1");
}
return 0;
}
B
题解
类型:数学
相当于要去求 ⌊logbase(n!)⌋+1 预处理出 ln(n!) 然后转换成 base 为底即可。
#include <iostream>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <cstring>
#include <stack>
#include <queue>
#include <string>
#include <vector>
#include <set>
#include <map>
#define pb push_back
#define mp make_pair
#define all(x) (x).begin(),(x).end()
#define sz(x) ((int)(x).size())
#define fi first
#define se second
using namespace std;
typedef long long LL;
typedef vector<int> VI;
typedef pair<int,int> PII;
LL powmod(LL a,LL b, LL MOD) {LL res=1;a%=MOD;for(;b;b>>=1){if(b&1)res=res*a%MOD;a=a*a%MOD;}return res;}
// head
const int N = 1E6+5;
double a[N];
int main()
{
for (int i = 1; i <= 1000000; i++) {
a[i] = a[i-1]+log(i);
}
int t, n, m, cas = 1;
scanf("%d", &t);
while (t--) {
scanf("%d%d", &n, &m);
printf("Case %d: %.0f\n", cas++, 1+floor(a[n]/log(m)));
}
return 0;
}
C
题解
类型:枚举
数据很宽松,直接立方暴力即可,当然有更快的做法,我想到最好的是常数较大的线性。
#include <iostream>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <cstring>
#include <stack>
#include <queue>
#include <string>
#include <vector>
#include <set>
#include <map>
#define pb push_back
#define mp make_pair
#define all(x) (x).begin(),(x).end()
#define sz(x) ((int)(x).size())
#define fi first
#define se second
using namespace std;
typedef long long LL;
typedef vector<int> VI;
typedef pair<int,int> PII;
LL powmod(LL a,LL b, LL MOD) {LL res=1;a%=MOD;for(;b;b>>=1){if(b&1)res=res*a%MOD;a=a*a%MOD;}return res;}
// head
const int N = 105;
int a[N];
int main()
{
int n, ans = 0;
scanf("%d", &n);
for (int i = 0; i < n; i++) {
scanf("%d", a+i);
}
for (int i = 0; i < n; i++) {
for (int j = i; j < n; j++) {
int temp = 0;
for (int k = i; k <= j; k++) {
temp ^= a[k];
}
ans = max(ans, temp);
}
}
printf("%d\n", ans);
return 0;
}
D
题解
类型:贪心
需要绕一定弯的贪心,首先一定是长度越长越好,长度相同高权位越大越好。于是可以先确定下来最终的位数,即以最小的数字先去取好,然后将代价和总花费进行偏移,就能以0为分界点去做了。
#include <iostream>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <cstring>
#include <stack>
#include <queue>
#include <string>
#include <vector>
#include <set>
#include <map>
#define pb push_back
#define mp make_pair
#define all(x) (x).begin(),(x).end()
#define sz(x) ((int)(x).size())
#define fi first
#define se second
using namespace std;
typedef long long LL;
typedef vector<int> VI;
typedef pair<int,int> PII;
LL powmod(LL a,LL b, LL MOD) {LL res=1;a%=MOD;for(;b;b>>=1){if(b&1)res=res*a%MOD;a=a*a%MOD;}return res;}
// head
int a[15];
int main()
{
int n, len = 0, minv = 1e9;
scanf("%d", &n);
for (int i = 1; i <= 9; i++) {
scanf("%d", a+i);
len = max(len, n/a[i]);
minv = min(minv, a[i]);
}
if (len == 0) {
puts("-1");
return 0;
}
for (int i = 1; i <= 9; i++) {
a[i] -= minv;
}
n -= minv*len;
for (int i = 0; i < len; i++) {
for (int j = 9; j > 0; j--) {
if (a[j] <= n) {
n -= a[j];
putchar('0'+j);
break;
}
}
}
return 0;
}
E
题解
类型:并查集
维护连通性使用并查集,弄个数组维护有没有出现骑士。不断维护祖先的最大值,在合并时进行更新即可。根据维护的数据输出结果。比较好想到,代码还是有点长的。
#include <iostream>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <cstring>
#include <stack>
#include <queue>
#include <string>
#include <vector>
#include <set>
#include <map>
#define pb push_back
#define mp make_pair
#define all(x) (x).begin(),(x).end()
#define sz(x) ((int)(x).size())
#define fi first
#define se second
using namespace std;
typedef long long LL;
typedef vector<int> VI;
typedef pair<int,int> PII;
LL powmod(LL a,LL b, LL MOD) {LL res=1;a%=MOD;for(;b;b>>=1){if(b&1)res=res*a%MOD;a=a*a%MOD;}return res;}
// head
const int N = 1005;
const int M = N*N;
int fa[M];
int v[M];
bool vis[N][N];
int find(int key) {
return (key == fa[key]) ? key : (fa[key] = find(fa[key]));
}
void init(int n) {
for (int i = 0; i < n; i++) {
fa[i] = i;
}
}
void joint(int a, int b) {
a = find(a), b = find(b);
if (a != b) {
fa[a] = b;
v[b] = max(v[b], v[a]);
}
}
bool same(int u, int v) {
return find(u) == find(v);
}
int t, n, q, x, y, val;
int dx[4] = {0, 0, 1, -1};
int dy[4] = {1, -1, 0, 0};
bool isok(PII &cur) {
return cur.fi > 0 && cur.fi <= n && cur.se > 0 && cur.se <= n;
}
int convert(int x, int y) {
return (x-1)*n+y-1;
}
char s[5];
int main()
{
char ch;
scanf("%d", &t);
while (t--) {
scanf("%d%d", &n, &q);
init(n*n);
for (int i = 0; i < q; i++) {
scanf("%s%d%d", s, &x, &y);
if (s[0] == 'C') {
scanf("%d", &val);
for (int dir = 0; dir < 4; dir++) {
PII nxt = mp(x + dx[dir], y + dy[dir]);
if (isok(nxt) && vis[nxt.fi][nxt.se]) {
joint(convert(x, y), convert(nxt.fi, nxt.se));
}
}
int pos = find(convert(x, y));
v[pos] = max(v[pos], val);
vis[x][y] = true;
} else {
int pos = find(convert(x, y));
printf("%d\n", vis[x][y] ? v[pos] : -1);
}
}
memset(vis, 0, sizeof vis);
memset(v, 0, sizeof v);
}
return 0;
}