题目
戳这里看题目,密码:ktix
戳这里看三道题的题解,密码:m65h
丧心病狂的你居然想看我们的成绩
Johann是蒟蒻,Orz众神犇
T1 DEC
可以用map哈希,也可以二分
#include <bits/stdc++.h>
using namespace std;
#define rep(i, a, b) for(int i = (a); i <= (b); i++)
#define red(i, a, b) for(int i = (a); i >= (b); i--)
#define ll long long
const int N = 300000;
map<int, int> hash;
int a[N];
int n, c;
ll ans;
inline int read() {
int x = 0, f = 1;
char ch = getchar();
while(!isdigit(ch)) {
if (ch == '-') f = -1;
ch = getchar();
}
while(isdigit(ch)) {
x = x * 10 + ch - '0';
ch = getchar();
}
return x * f;
}
int main() {
freopen("dec.in", "r", stdin);
freopen("dec.out", "w", stdout);
scanf("%d%d", &n, &c);
rep(i, 1, n) {
a[i] = read();
hash[a[i]]++;
}
ans = 0;
int x;
rep(i, 1, n) {
x = a[i] + c;
ans += (ll)(hash[x]);
}
printf("%I64d\n", ans);
return 0;
}
T2 COUNT
对任意n,例如1234.
先考虑n个数中个位上分别是1~9的个数,先来看1230,显然1230里个位是1的数有123个,2到9也是123个。
那么没统计的数字就是1230,1231,1232,1233,1234这5个,显然个位是1的又增加5个。
再来看十位:类似的来看1200,则十位是1~9的数各有120个,剩下还有1201~1234,则十位是1~2的个数分别增加10个,十位是3的增加5个.
以此类推
#include <bits/stdc++.h>
using namespace std;
#define rep(i, a, b) for(int i = (a); i <= (b); i++)
#define red(i, a, b) for(int i = (a); i >= (b); i--)
#define ll long long
ll cnt[10] = {0};
ll n;
int main() {
freopen("count.in", "r", stdin);
freopen("count.out", "w", stdout);
scanf("%I64d", &n);
ll p = 1, m = 0, x = n;
while(x) {
m++;
x /= 10ll;
}
while(m--) {
p *= 10ll;
ll t = (n / p) * p;
rep(i, 1, 9) cnt[i] += t / 10;
t = n - t;
x = t / (p / 10);
rep(i, 1, x - 1) cnt[i] += p / 10;
cnt[x] += t - x * (p / 10) + 1;
}
ll ans = 0;
rep(i, 1, 9) ans += cnt[i] * (ll)(i);
printf("%I64d\n", ans);
return 0;
}
T3 SWITCH
对于每个状态,算法只需要枚举第一行改变哪些灯的状态,只要第一行的状态固定了,接下来的状态改变方法都是唯一的:每一行需要改变状态的位置都在上一行中不亮的灯的正下面,因为只有这样才能使上一行的灯全亮。我们枚举第一行的状态改变方法(共 25 种),对于每种方法都依次改变下面几行的状态使上面一行灯全亮。到最后一行我们需要判断是否最后一行也恰好全亮,并更新最小步数。
#include <bits/stdc++.h>
using namespace std;
#define rep(i, a, b) for(int i = (a); i <= (b); i++)
#define red(i, a, b) for(int i = (a); i >= (b); i--)
#define ll long long
const int inf = 1000000000;
int a[10][10], back_up[10][10];
int T;
int main() {
freopen("switch.in", "r", stdin);
freopen("switch.out", "w", stdout);
scanf("%d", &T);
while(T--) {
int ans = inf;
memset(a, 0, sizeof(a));
rep(i, 1, 5) {
char ch = '#';
while(!isdigit(ch)) ch = getchar();
rep(j, 1, 5) {
a[i][j] = ch - '0';
back_up[i][j] = a[i][j];
ch = getchar();
}
}
rep(sol, 0, 31) {
int k = sol, cnt = 0, j = 0;
while(k) {
j++;
if (k & 1) {
a[1][j] ^= 1;
a[0][j] ^= 1;
a[2][j] ^= 1;
a[1][j - 1] ^= 1;
a[1][j + 1] ^= 1;
cnt++;
}
k >>= 1;
}
rep(i, 2, 5) {
rep(j, 1, 5) {
if (a[i - 1][j] == 0) {
cnt++;
a[i - 1][j] ^= 1;
a[i][j] ^= 1;
a[i + 1][j] ^= 1;
a[i][j - 1] ^= 1;
a[i][j + 1] ^= 1;
}
}
}
int tag = 1;
rep(i, 1, 5)
if (a[5][i] == 0) {
tag = 0; break;
}
if (cnt < ans && tag) ans = cnt;
rep(i, 1, 5) rep(j, 1, 5) a[i][j] = back_up[i][j];
}
if (ans <= 6) printf("%d\n", ans);
else printf("-1\n");
}
return 0;
}
T4 ORZ
题面不错
至于题目内容么,送到手的
n2
DP
#include <bits/stdc++.h>
using namespace std;
#define rep(i, a, b) for(int i = (a); i <= (b); i++)
#define red(i, a, b) for(int i = (a); i >= (b); i--)
#define ll long long
const int inf = 1000000000, N = 3000;
int cnt[5], f[N], a[N];
int n, m;
int main() {
freopen("orz.in", "r", stdin);
freopen("orz.out", "w", stdout);
scanf("%d%d", &n, &m);
rep(i, 1, n) scanf("%d", &a[i]);
rep(i, 1, n) f[i] = inf;
rep(i, 1, n) {
memset(cnt, 0, sizeof(cnt));
red(j, i, 1) {
cnt[a[j]]++;
if (cnt[1] == 0 || cnt[2] == 0 || fabs(cnt[1] - cnt[2]) <= m) {
f[i] = min(f[j - 1] + 1, f[i]);
}
}
}
printf("%d\n", f[n]);
return 0;
}
T5 TREECUT
就是求树的重心
没了
#include <bits/stdc++.h>
using namespace std;
#define rep(i, a, b) for(int i = (a); i <= (b); i++)
#define red(i, a, b) for(int i = (a); i >= (b); i--)
#define ll long long
const int N = 20000;
struct edge{
int u, v, nxt;
}e[N];
int head[N], sum[N], fa[N], lis[N];
int n, lim, num, tail = 0;
inline int read() {
int x = 0, f = 1; char ch = getchar();
while(!isdigit(ch)) { if (ch == '-') f = -1; ch = getchar(); }
while(isdigit(ch)) { x = x * 10 + ch - '0'; ch = getchar(); }
return x * f;
}
void addedge(int x, int y) {
e[++tail].u = x;
e[tail].v = y;
e[tail].nxt = head[x];
head[x] = tail;
}
void BFS(int x) {
int m = n; fa[x] = -1;
queue<int> q;
q.push(x);
while(!q.empty()) {
int u = q.front(); q.pop();
lis[m--] = u;
for(int i = head[u]; i != -1; i = e[i].nxt) {
int v = e[i].v;
if (v != fa[u]) {
fa[v] = u;
q.push(v);
}
}
}
}
int main() {
freopen("treecut.in", "r", stdin);
freopen("treecut.out", "w", stdout);
scanf("%d", &n);
lim = n / 2; num = 0;
rep(i, 1, n) head[i] = -1, sum[i] = 1;
rep(i, 1, n - 1) {
int x, y;
scanf("%d%d", &x, &y);
addedge(x, y);
addedge(y, x);
}
BFS(1);
rep(i, 1, n) {
int u = lis[i];
for(int j = head[u]; j != -1; j = e[j].nxt) {
if (e[j].v == fa[u]) continue;
sum[u] += sum[e[j].v];
}
}
rep(i, 1, n) {
if (n - sum[i] > lim) continue;
int tag = 1, u = i;
for(int j = head[u]; j != -1; j = e[j].nxt) {
int v = e[j].v;
if (v == fa[u]) continue;
if (sum[v] > lim) {
tag = 0;
break;
}
}
if (tag) { printf("%d\n", i); num++; }
}
if (!num) printf("NONE\n");
return 0;
}
尾声
于是水题的题解就十分速度的写完了
居然AK了呢
这套题自己还做过的,当时只做了190,突然发现自己还是有过进步的
听说要月考?停课是第一生产力
老大的有机化学