總結——關於2017 10 23測試的分析總結

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;
}






T3 :



题目:





——正解思路:

其实各种方法都可以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;
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值