这题为什么hash不保存步数会wa。
查看原帖
这题为什么hash不保存步数会wa。
66181
Celebrate楼主2020/10/15 22:09

我一开始的代码是

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <cmath>
#include <queue>
#define LL long long
using namespace std;

const int P = 999983, N = 3100000;

int Head[P], tot, Next[N];
struct node { int x, dep; } a[N];
struct rec { int i, F, L; };
int n, m, mc, mx, day, f[110][110], b[N], c[N], w[N];

void insert(int x, int dep) {
	tot++; int t = x % P;
	a[tot] = (node){x, dep};
	Next[tot] = Head[t];
	Head[t] = tot;
}

bool search(int x, int dep) {
	int t = x % P;
	for (int i = Head[t]; i; i = Next[i])
		if (a[i].x == x) return 1;
	return 0;
}

void mymax(int &x, int y) { x = x > y ? x : y; }

bool cmp(node p1, node p2) {
	return p1.x == p2.x ? p1.dep < p2.dep : p1.x < p2.x;
}

void bfs() {
	queue<rec> q;
	q.push((rec){1, 1, 0});
	while (q.size()) {
		rec x = q.front(); q.pop();
		if (x.i == day) break;
		q.push((rec){x.i + 1, x.F, x.L + 1});
		if (x.L > 1 && (LL)x.F * x.L <= mx && !search(x.F * x.L, x.i + 1)) {
			insert(x.F * x.L, x.i + 1);
			q.push((rec){x.i + 1, x.F * x.L, x.L});
		}
	}
}

int main() {
//	freopen("dalao5.in", "r", stdin);
//	freopen("7.out", "w", stdout);
	cin >> n >> m >> mc;
	for (int i = 1; i <= n; i++) cin >> b[i];
	for (int i = 1; i <= n; i++) cin >> w[i];
	for (int i = 1; i <= m; i++) cin >> c[i], mymax(mx, c[i]);
	memset(f, 0xcf, sizeof(f)); f[0][mc] = 0;
	for (int i = 1; i <= n; i++)
		for (int j = b[i]; j <= mc; j++) {
			mymax(f[i][j - b[i]], f[i - 1][j] + 1);
			mymax(f[i][min(mc, j - b[i] + w[i])], f[i - 1][j]);
		}
	for (int i = 1; i <= n; i++)
		for (int j = 0; j <= mc; j++)
			mymax(day, f[i][j]);
	bfs();
	sort(a + 1, a + tot + 1, cmp);
	/* 
	for (int i = 1; i <= tot; i++)
		for (int j = 1; j < i; j++)
			if (a[i].x + a[j].x <= c[1] && a[i].dep + a[j].dep <= day && a[i].x + a[j].x + day - a[i].dep - a[j].dep >= c[1])
				printf("%d %d\n", i, j);*/ 
	
	for (int i = 1; i <= m; i++) {
		if (c[i] <= day) { puts("1"); continue; }
		bool flag = 0;
		int minn = 1e9;
		for (int l = 1, r = tot; r >= 1; r--) {
			while (l <= tot && a[l].x + a[r].x <= c[i]) {
				minn = min(minn, a[l].dep - a[l].x);
				l++;
			}
			if ((LL)a[r].x + day - a[r].dep >= c[i] + minn) { flag = 1; break; }
			if (a[r].x <= c[i] && a[r].x + day - a[r].dep >= c[i]) { flag = 1; break; }
		}
		puts(flag ? "1" : "0");
	}
	
	return 0;
}

把search函数中的if改成

if (a[i].x == x && a[i].dep == dep) return 1;

就能ac 修改完后的代码

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <cmath>
#include <queue>
#define LL long long
using namespace std;

const int P = 999983, N = 3100000;

int Head[P], tot, Next[N];
struct node { int x, dep; } a[N];
struct rec { int i, F, L; };
int n, m, mc, mx, day, f[110][110], b[N], c[N], w[N];

void insert(int x, int dep) {
	tot++; int t = x % P;
	a[tot] = (node){x, dep};
	Next[tot] = Head[t];
	Head[t] = tot;
}

bool search(int x, int dep) {
	int t = x % P;
	for (int i = Head[t]; i; i = Next[i])
		if (a[i].x == x && a[i].dep == dep) return 1;
	return 0;
}

void mymax(int &x, int y) { x = x > y ? x : y; }

bool cmp(node p1, node p2) {
	return p1.x == p2.x ? p1.dep < p2.dep : p1.x < p2.x;
}

void bfs() {
	queue<rec> q;
	q.push((rec){1, 1, 0});
	while (q.size()) {
		rec x = q.front(); q.pop();
		if (x.i == day) break;
		q.push((rec){x.i + 1, x.F, x.L + 1});
		if (x.L > 1 && (LL)x.F * x.L <= mx && !search(x.F * x.L, x.i + 1)) {
			insert(x.F * x.L, x.i + 1);
			q.push((rec){x.i + 1, x.F * x.L, x.L});
		}
	}
}

int main() {
//	freopen("dalao5.in", "r", stdin);
//	freopen("7.out", "w", stdout);
	cin >> n >> m >> mc;
	for (int i = 1; i <= n; i++) cin >> b[i];
	for (int i = 1; i <= n; i++) cin >> w[i];
	for (int i = 1; i <= m; i++) cin >> c[i], mymax(mx, c[i]);
	memset(f, 0xcf, sizeof(f)); f[0][mc] = 0;
	for (int i = 1; i <= n; i++)
		for (int j = b[i]; j <= mc; j++) {
			mymax(f[i][j - b[i]], f[i - 1][j] + 1);
			mymax(f[i][min(mc, j - b[i] + w[i])], f[i - 1][j]);
		}
	for (int i = 1; i <= n; i++)
		for (int j = 0; j <= mc; j++)
			mymax(day, f[i][j]);
	bfs();
	sort(a + 1, a + tot + 1, cmp);
	/* 
	for (int i = 1; i <= tot; i++)
		for (int j = 1; j < i; j++)
			if (a[i].x + a[j].x <= c[1] && a[i].dep + a[j].dep <= day && a[i].x + a[j].x + day - a[i].dep - a[j].dep >= c[1])
				printf("%d %d\n", i, j);*/ 
	
	for (int i = 1; i <= m; i++) {
		if (c[i] <= day) { puts("1"); continue; }
		bool flag = 0;
		int minn = 1e9;
		for (int l = 1, r = tot; r >= 1; r--) {
			while (l <= tot && a[l].x + a[r].x <= c[i]) {
				minn = min(minn, a[l].dep - a[l].x);
				l++;
			}
			if ((LL)a[r].x + day - a[r].dep >= c[i] + minn) { flag = 1; break; }
			if (a[r].x <= c[i] && a[r].x + day - a[r].dep >= c[i]) { flag = 1; break; }
		}
		puts(flag ? "1" : "0");
	}
	
	return 0;
}
2020/10/15 22:09
加载中...