NOIP2017 Day1 题解

去年水平不行,导致noip滚粗,现在来复习一下,今年要小心了。

A - 小凯的疑惑

裴蜀定理。

//waz
#include <bits/stdc++.h>

using namespace std;

#define mp make_pair
#define pb push_back
#define fi first
#define se second
#define ALL(x) (x).begin(), (x).end()
#define SZ(x) ((int)((x).size()))

typedef pair<int, int> PII;
typedef vector<int> VI;
typedef long long int64;
typedef unsigned int uint;
typedef unsigned long long uint64;

#define gi(x) ((x) = F())
#define gii(x, y) (gi(x), gi(y))
#define giii(x, y, z) (gii(x, y), gi(z))

int F()
{
	char ch;
	int x, a;
	while (ch = getchar(), (ch < '0' || ch > '9') && ch != '-');
	if (ch == '-') ch = getchar(), a = -1;
	else a = 1;
	x = ch - '0';
	while (ch = getchar(), ch >= '0' && ch <= '9')
		x = (x << 1) + (x << 3) + ch - '0';
	return a * x;
}

int a, b;

int main()
{
	gii(a, b);
	printf("%lld\n", (a - 1LL) * (b - 1LL) - 1);
}

  

B - 时间复杂度

用个栈模拟一下。

//waz
#include <bits/stdc++.h>

using namespace std;

#define mp make_pair
#define pb push_back
#define fi first
#define se second
#define ALL(x) (x).begin(), (x).end()
#define SZ(x) ((int)((x).size()))

typedef pair<int, int> PII;
typedef vector<int> VI;
typedef long long int64;
typedef unsigned int uint;
typedef unsigned long long uint64;

#define gi(x) ((x) = F())
#define gii(x, y) (gi(x), gi(y))
#define giii(x, y, z) (gii(x, y), gi(z))

int F()
{
	char ch;
	int x, a;
	while (ch = getchar(), (ch < '0' || ch > '9') && ch != '-');
	if (ch == '-') ch = getchar(), a = -1;
	else a = 1;
	x = ch - '0';
	while (ch = getchar(), ch >= '0' && ch <= '9')
		x = (x << 1) + (x << 3) + ch - '0';
	return a * x;
}

void solve()
{
	int L;
	static char fzd[233];
	gi(L);
	scanf("%s", fzd + 1);
	int w = 0;
	if (fzd[3] == 'n') sscanf(fzd + 1, "O(n^%d)", &w);
	static pair<int, char> stk[233];// (x > y : -1) (x <= y : 0) (x = c, y = n : 1)
	int tp = 0;
	static bool in[233];
	static int mx[233];
	memset(mx, 0, sizeof mx);
	memset(in, 0, sizeof in);
	bool flag = 1;
	for (int i = 1; i <= L; ++i)
	{
		char ch;
		while (ch = getchar(), ch != 'F' && ch != 'E');
		if (ch == 'F')
		{
			while (ch = getchar(), ch < 'a' || ch > 'z');
			static char x[10], y[10];
			scanf("%s%s", x + 1, y + 1);
			if (in[ch])
				flag = 0;
			if (!flag) continue;
			in[ch] = 1;
			if (x[1] == 'n' && y[1] == 'n')
			{
				stk[++tp] = mp(0, ch);
			}
			else if (x[1] == 'n' && y[1] != 'n')
			{
				stk[++tp] = mp(-1, ch);
			}
			else if (y[1] == 'n')
			{
				stk[++tp] = mp(1, ch);
			}
			else
			{
				int X, Y;
				sscanf(x + 1, "%d", &X);
				sscanf(y + 1, "%d", &Y);
				if (X <= Y) stk[++tp] = mp(0, ch);
				else stk[++tp] = mp(-1, ch);
			}
		}
		else
		{
			if (!tp) flag = 0;
			if (!flag) continue;
			if (stk[tp].fi == 1) mx[tp - 1] = max(mx[tp - 1], mx[tp] + 1);
			else if (stk[tp].fi == 0) mx[tp - 1] = max(mx[tp - 1], mx[tp]);
			in[stk[tp].se] = 0;
			mx[tp] = 0;
			--tp;
		}
	}
	if (tp || !flag)
	{
		puts("ERR");
		return;
	}
	if (mx[0] == w)
	{
		puts("Yes");
	}
	else
	{
		//cerr << mx[0] << endl;
		puts("No");
	}
}

int main()
{
	int T;
	gi(T);
	while (T--)
		solve();
}

  

C - 逛公园

用最短路算法判断哪些点一定不会走到,先删除掉,接着建出拓扑图,如果所有没有0环是一个有向无环图,判断一下就好了。(之前还写了个智障tarjan)

//waz
#include <bits/stdc++.h>

using namespace std;

#define mp make_pair
#define pb push_back
#define fi first
#define se second
#define ALL(x) (x).begin(), (x).end()
#define SZ(x) ((int)((x).size()))

typedef pair<int, int> PII;
typedef vector<int> VI;
typedef long long int64;
typedef unsigned int uint;
typedef unsigned long long uint64;

#define gi(x) ((x) = F())
#define gii(x, y) (gi(x), gi(y))
#define giii(x, y, z) (gii(x, y), gi(z))

int F()
{
	char ch;
	int x, a;
	while (ch = getchar(), (ch < '0' || ch > '9') && ch != '-');
	if (ch == '-') ch = getchar(), a = -1;
	else a = 1;
	x = ch - '0';
	while (ch = getchar(), ch >= '0' && ch <= '9')
		x = (x << 1) + (x << 3) + ch - '0';
	return a * x;
}

const int N = 1e5 + 10, M = 2e5 + 10;

int n, m, k, p, lim;

struct edge { int to, val; edge *next; };

struct graph
{
	edge e[M], *la[N], *et;
	int d[N];
	graph() { et = e; }
	void clear() { memset(la, 0, sizeof la); et = e; }
	void add(int u, int v, int w) { *++et = (edge) {v, w, la[u]}, la[u] = et; }
	void dijkstra(int s)
	{
		memset(d, 63, sizeof d);
		priority_queue<PII> pq;
		pq.push(mp(0, s)); d[s] = 0;
		while (!pq.empty())
		{
			PII x = pq.top(); pq.pop();
			if (d[x.se] != -x.fi) continue;
			int u = x.se;
			for (edge *it = la[u]; it; it = it -> next)
			{
				int v = it -> to, w = it -> val;
				if (d[v] > d[u] + w)
				{
					d[v] = d[u] + w;
					pq.push(mp(-d[v], v));
				}
			}
		}
	}
} G1, G2, G;

void make_G()
{
	G.clear();
	static int ok[N];
	int idt = 0;
	memset(ok, 0, sizeof ok);
	for (int i = 1; i <= n; ++i)
		if (G1.d[i] + G2.d[i] <= lim + k) ok[i] = ++idt;
	for (int i = 1; i <= n; ++i)
	{
		if (ok[i])
		{
			for (edge *it = G1.la[i]; it; it = it -> next)
			{
				if (ok[it -> to])
					G.add(i, it -> to, it -> val);
			}
		}
	}
	n = idt;
}

int id[N][51];

int f[N * 51], deg[N * 51];

struct eg { int to; eg *next; };

void solve()
{
	giii(n, m, k), gi(p);
	G1.clear(), G2.clear();
	for (int i = 1; i <= m; ++i)
	{
		int a, b, c;
		giii(a, b, c);
		G1.add(a, b, c);
		G2.add(b, a, c);
	}
	lim = G1.d[n];
	make_G();
	G.dijkstra(1);
	int idt = 0;
	static eg e[M * 51], *la[N * 51];
	eg *et = e;
	for (int i = 1; i <= n; ++i)
		for (int j = 0; j <= k; ++j)
			id[i][j] = ++idt, la[idt] = 0, f[idt] = deg[idt] = 0;
	for (int i = 1; i <= n; ++i)
	{
		for (edge *it = G.la[i]; it; it = it -> next)
		{
			int j = it -> to;
			for (int l = 0; l <= k; ++l)
			{
				int u = id[i][l];
				int dis = G.d[i] + l + (it -> val) - G.d[j];
				if (dis <= k && dis >= 0) 
				{
					int v = id[j][dis];
					*++et = (eg) {v, la[u]}, la[u] = et; ++deg[v];
				}
			}
		}
	}
	static int q[N * 51]; int l = 0, r = 0;
	for (int i = 1; i <= idt; ++i) if (!deg[i]) q[r++] = i;
	f[id[1][0]] = 1;
	while (l < r)
	{
		int u = q[l++];
		for (eg *it = la[u]; it; it = it -> next)
		{
			int v = it -> to;
			f[v] = (f[v] + f[u]) % p;
			--deg[v];
			if (!deg[v]) q[r++] = v;
		}
	}
	int ans = 0;
	for (int i = 0; i <= k; ++i)
		ans = (ans + f[id[n][i]]) % p;
	if (r != idt)
	{
		puts("-1");
		return;
	}
	printf("%d\n", ans);
}

int main()
{
	int T;
	gi(T);
	while (T--) solve();
}

  

 

posted @ 2018-09-12 21:20  AnzheWang  阅读(357)  评论(0编辑  收藏  举报