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\)
咕咕咕~