9.18胡测

\(A\)

传送门

用哈希表去下重即可。

#include <iostream>
#include <cstdio>
#include <cstring>

using namespace std;

#define ll long long

const int MOD = 1000037;
const int jia = 1000000001;

int n, x0, y0, xt, yt, ans;

ll tmpx, tmpy, to[1000050];

int head[MOD + 50], nxt[1000050], num;

void Read(int &x)
{
	x = 0; int p = 0; char st = getchar();
	while (st < '0' || st > '9') p = (st == '-'), st = getchar();
	while (st >= '0' && st <= '9') x = (x << 1) + (x << 3) + st - '0', st = getchar();
	x = p ? -x : x;
	return; 
}

int Insert(ll x)
{
	int pos = x % MOD;
	for (int i = head[pos]; i; i = nxt[i])
		if (to[i] == x) return 0;
	num++;
	nxt[num] = head[pos];
	to[num] = x;
	head[pos] = num;
	return 1;
}

int main()
{
//	freopen("loverfinding1.in", "r", stdin);
	Read(n); Read(x0); Read(y0); Read(xt); Read(yt);
	tmpx = 0LL + x0 + jia; tmpy = 0LL + y0 + jia;
	Insert(tmpx * 1000000000 + tmpy); ans++;
	for (int i = 1, x, y; i <= n; i++)
	{
		Read(x); Read(y);
		x0 += x; y0 += y;
		tmpx = 0LL + x0 + jia; tmpy = 0LL + y0 + jia;
		if (x0 == xt && y0 == yt) { printf("%d\n", ans + 1); return 0; }
		if (Insert(tmpx * 1000000000 + tmpy)) ans++;
	}
	puts("SingleDogMZX");
	return 0;
}

\(B\)

传送门

如果预处理出\(dp_{i, j, k}\)表示用前\(i\)大的点做松弛,\(j\)\(k\)的最短距离,那么我们就可以用两次二分求出答案。

发现\(dp\)数组其实就是原始的\(Floyd\)再排序一下。

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>

using namespace std;

#define int long long

const int INF = 1e18 + 5;
const int N = 100;

int n, m, q, dis[N + 50][N + 50][N + 50];

struct Node
{
	int id, v;
} a[N + 50];

void Read(int &x)
{
	x = 0; int p = 0; char st = getchar();
	while (st < '0' || st > '9') p = (st == '-'), st = getchar();
	while (st >= '0' && st <= '9') x = (x << 1) + (x << 3) + st - '0', st = getchar();
	x = p ? -x : x;
	return;
}

int Cmp(Node a, Node b)
{
	return a.v < b.v;
} 

signed main()
{
	Read(n); Read(m); Read(q);
	for (int i = 1; i <= n; i++) Read(a[i].v), a[i].id = i;
	for (int i = 1; i <= n; i++)
		for (int j = 1; j <= n; j++)
			dis[0][i][j] = INF;
	for (int i = 1; i <= n; i++)
		dis[0][i][i] = 0;
	for (int i = 1, u, v, w; i <= m; i++)
	{
		Read(u); Read(v); Read(w);
		dis[0][u][v] = dis[0][v][u] = min(dis[0][u][v], w);
	}
	sort(a + 1, a + n + 1, Cmp);
	for (int k = 1; k <= n; k++)
	{
		for (int i = 1; i <= n; i++)
			for (int j = 1; j <= n; j++)
				dis[k][i][j] = dis[k - 1][i][j];
		for (int i = 1; i <= n; i++)
			for (int j = 1; j <= n; j++)
				if (i != j && i != a[k].id && j != a[k].id)
					if (dis[k - 1][i][a[k].id] != INF && dis[k - 1][a[k].id][j] != INF)
						dis[k][i][j] = min(dis[k][i][j], dis[k - 1][i][a[k].id] + dis[k - 1][a[k].id][j]);
	}
	for (int k = 0; k <= n; k++)
		for (int i = 1; i <= n; i++)
			sort(dis[k][i] + 1, dis[k][i] + n + 1);
	for (int cs = 1, s, c, d; cs <= q; cs++)
	{
		Read(s); Read(c); Read(d);
		int l = 0, r = n;
		while (l < r)
		{
			int mid = (l + r + 1) >> 1;
			if (a[mid].v <= c) l = mid;
			else r = mid - 1;	
		} 
		int tmp = l;
		l = 0, r = n;
		while (l < r)
		{
			int mid = (l + r + 1) >> 1;
			if (dis[tmp][s][mid] <= d) l = mid;
			else r = mid - 1;
		}
		printf("%lld\n", l - 1); 
	}
	return 0;
}

\(C\)

传送门

咕咕咕~

posted @ 2020-09-21 17:22  Tian-Xing  阅读(97)  评论(0编辑  收藏  举报