NOIP 2017 模拟
10 23
T1 :
题目:
——正解思路:
因为斐波那契数列增长很快,所以1e+9以内的数不超过50个,先预处理再O( 1 )判断即可。
——我的乱搞:
**没有乱搞,同正解。
tips:
珍惜这些弱智题,毕竟明天凯爷又要 hehehe 了。。。。
代码:
#include <iostream>
#include <fstream>
#include <map>
int t, n, f[46] = {0, 1};
std::map <int, bool> m;
int main () {
for (int i = 2; i < 45; i++) f[i] = f[i - 1] + f[i - 2];
for (int i = 0; i < 45; i++) m[f[i]] = true;
std::cin>>t;
while (t--) {
std::cin>>n;
if (n == 0) {std::cout<<"Yes"<<std::endl; continue;}
for (int i = 1; f[i] <= n and i < 45; i++) {
if (n % f[i]) continue;
if (m[n / f[i]]) {std::cout<<"Yes"<<std::endl; goto Con;}
}
std::cout<<"No"<<std::endl;
Con : ;
}
return 0;
}
T2 :
题目:
——题目正解:
LCA求中点。
——我的乱搞:
迪杰斯特拉暴搜。
tips:
中规中矩的暴力,不过在暴力之前貌似我又把LCA背拐了曳。。。。
#include <fstream>
#define U(x, y) for (int i = x; i <= y; i++)
#define D for (int i = 17; i >= 0; i--)
#define N 100010
int n, m, x, y, z, a, c;
int t[N * 2], e[N * 2], d[N], s[N], r[N], f[N][18];
void R (int &x) {
x = 0;
char c = 0;
while (!isdigit(c)) c = getchar();
while (isdigit(c)) x = x * 10 + c - 48, c = getchar();
}
void A (int x, int y) {
t[++c] = y;
e[c] = s[x];
s[x] = c;
}
void T (int x, int F) {
d[x] = d[F] + 1;
f[x][0] = F;
U(1, 17) f[x][i] = f[f[x][i - 1]][i - 1];
for (int i = s[x]; i; i = e[i]) if (!d[t[i]]) {
T (t[i], x);
r[x] += r[t[i]];
}
}
int L (int x, int y) {
int E = d[x] - d[y];
D if (E & (1 << i)) x = f[x][i];
if (x == y) return x;
D if (f[x][i] != f[y][i]) x = f[x][i], y = f[y][i];
return f[x][0];
}
int main () {
R(n);
U(2, n) {
R(x);
R(y);
A (x, y);
A (y, x);
r[i] = 1;
}
r[1] = 1;
~d[0];
T (1, 0);
R(m);
while (m--) {
R(x);
R(y);
if (x == y) {
printf ("%d\n", n);
continue;
}
if (d[x] < d[y]) std::swap (x, y);
z = L (x, y);
c = d[x] + d[y] - d[z] * 2;
if (c & 1) {
puts("0");
continue;
}
--c >>= 1;
if (d[x] == d[y]) {
D if (c & (1 << i)) x = f[x][i], y = f[y][i];
a = r[1] - r[x] - r[y];
} else {
D if (c & (1 << i)) x = f[x][i];
a = r[f[x][0]] - r[x];
}
printf ("%d\n", a);
}
return 0;
}
题目:
——正解思路:
其实各种方法都可以Ac,dp, dfs, 最大流神马的都可以。
——我的乱搞:
推出了dfs前一半思路,后面乱搞,,,,,结果,就像***一样炸成渣渣。。。。
#pragma GCC optimize("O3")
#include <fstream>
#include <cstring>
int t, n, k, x, cnt, ans, tot;
int to[200002], next[200002], first[100001];
bool vis[100001];
inline void read (int &x) {
x = 0;
char c = getchar();
while (!isdigit(c)) c = getchar();
while (isdigit(c)) x = x * 10 + c - 48, c = getchar();
}
inline void put (int x) {
cnt = 0;
char c[10];
do c[++cnt] = x % 10 + 48, x /= 10; while(x);
while (cnt) putchar(c[cnt--]);
putchar('\n');
}
inline void add (int x, int y) {
to[++tot] = y;
next[tot] = first[x];
first[x] = tot;
}
void dfs (int x, int fa) {
for (int i = first[x]; i; i = next[i]) if (to[i] ^ fa) {
dfs (to[i], x);
if (!vis[to[i]] and !vis[x]) {
if (cnt < k) ++ans;
cnt += 2;
vis[to[i]] = vis[x] = true;
}
}
}
int main () {
read(t);
while (t--) {
memset (first, 0, sizeof(first));
memset (vis, 0, sizeof(vis));
tot = cnt = ans = 0;
read(n);
read(k);
for (int i = 2; i <= n; i++) {
read(x);
add (x, i);
add (i, x);
}
dfs (1, 0);
put (cnt < k ? ans + k - cnt : ans);
}
return 0;
}