【比赛】8.16

发布时间 2023-08-16 14:55:55作者: jiangchenyangsong

Ⅰ.LYK loves string


通过限定元素的先后可以将 \(10^10\) 优化成 \(10!\) ,再加一些剪枝就可以过了。

#include<bits/stdc++.h>
#define int long long
using namespace std;
const int mod = 1e9 + 7;
int read(){
	int x = 0, f = 1; char ch = getchar();
	while(ch < '0' || ch > '9'){if(ch == '-') f = -f; ch = getchar();}
	while(ch >= '0' && ch <= '9'){x = (x << 1) + (x << 3) + (ch ^ 48); ch = getchar();}
	return x * f; 
} 
int n, m, k, ans;
int f[15], g[15];
map<string, int> H;
void dfs(int fl, int sum, int tot, string now){
	if(sum > m || tot > k || g[n - fl + 1] + sum < m) return ;
	if(fl > n){
		if(sum != m) return ;
		ans = (ans + f[tot]) % mod;
		return ;
	}
	for(int i = tot + 1; i; --i){
		char y = i + 'a' - 1;
		string x = ""; x += y;
		int t = 0;
		if(!H[x]) ++t;
		++H[x];
		if(now.size()){
			for(int j = now.size() - 1; j >= 0; --j){
				x = now[j] + x;
				if(!H[x]) ++t;
				++H[x];
 			}
		} 
		string pre = now;
		x.clear();
		x += y;
		now += x;
		dfs(fl + 1, sum + t, tot + (i == tot + 1), now);
		now = pre;
		--H[x];
		if(now.size()){
			for(int j = now.size() - 1; j >= 0; --j){
				x = now[j] + x;
				--H[x];
 			}
		} 
	} 
}
signed main(){
//	freopen("string.in", "r", stdin);
//	freopen("string.out", "w", stdout);
	n = read(), m = read(), k = read();
	int x = k - 1; f[1] = k;
	for(int i = 2; i <= min(n, k); ++i) f[i] = f[i - 1] * x % mod, x --;
	x = n - 1; g[1] = n;
	for(int i = 2; i <= n; ++i) g[i] = g[i - 1] + x, x --;
	dfs(1, 0, 0, "");
	printf("%lld\n", ans);
//	fclose(stdin);
//	fclose(stdout);
	return 0;
} 

Ⅱ.LYK loves graph

分层图最短路,因为有些连通块不能一笔画,会漏解。所以有些情况往回走可以不加代价。具体看代码。

#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N = 3e2 + 67;
int read(){
	int x = 0, f = 1; char ch = getchar();
	while(ch < '0' || ch > '9'){if(ch == '-') f = -f; ch = getchar();}
	while(ch >= '0' && ch <= '9'){x = (x << 1) + (x << 3) + (ch ^ 48); ch = getchar();}
	return x * f; 
} 
int n, m, k, ans = 0x3f3f3f3f3f3f3f3f;
int c[N][N], a[N][N], dis[N * N * 7];
int dx[4] = {0, 0, 1, -1};
int dy[4] = {1, -1, 0, 0};
int id(int i, int j, int floor){
	return (i - 1) * m + j + (floor - 1) * n * m;
}
struct node{
	int dis, x, y, k;
	bool operator < (const node &A) const{return dis > A.dis;}
};
bitset<300> col[N * N * 7], mp[N * N * 7];
priority_queue<node> pq;
bool vis[N * N * 7];
bool check(int x, int y){
	if(x < 1 || x > n || y < 1 || y > m) return false;
	return true;
}
void solve(int sx, int sy, int sk){
	while(!pq.empty()) pq.pop();
	memset(dis, 0x3f, sizeof(dis));
	memset(vis, 0, sizeof(vis));
	for(int i = 1; i <= n * m * k; ++i) col[id(sx, sy, sk)].reset(), mp[id(sx, sy, sk)].reset();
	dis[id(sx, sy, sk)] = a[sx][sy];
	pq.push((node){a[sx][sy], sx, sy, sk});
	col[id(sx, sy, sk)][c[sx][sy]] = 1;
	mp[id(sx, sy, sk)][id(sx, sy, 1)] = 1;
	while(!pq.empty()){
		node now = pq.top(); pq.pop();
		int id1 = id(now.x, now.y, now.k), id2;
		if(vis[id1]) continue;
		vis[id1] = 1;
		if(now.k == k){
			ans = min(ans, dis[id1]);
			continue;
		}
		for(int i = 0; i < 4; ++i){
			int x = now.x + dx[i];
			int y = now.y + dy[i];
			if(!check(x, y) || c[x][y] == -1) continue;
			if(col[id1][c[x][y]]){
				id2 = id(x, y, now.k);
				if(dis[id2] > dis[id1] + a[x][y]){
					if(mp[id1][id(x, y, 1)]) dis[id2] = dis[id1];
					else dis[id2] = dis[id1] + a[x][y];
					col[id2] = col[id1];
					mp[id2] = mp[id1]; mp[id2][id(x, y, 1)] = 1;
					pq.push((node){dis[id2], x, y, now.k});
				}
			}else{
				id2 = id(x, y, now.k + 1);
				if(dis[id2] > dis[id1] + a[x][y]){
					dis[id2] = dis[id1] + a[x][y];
					col[id2] = col[id1]; col[id2][c[x][y]] = 1;
					mp[id2] = mp[id1]; mp[id2][id(x, y, 1)] = 1;
					pq.push((node){dis[id2], x, y, now.k + 1});
				}
			}
		}
	}
}
signed main(){
//	freopen("graph.in", "r", stdin);
//	freopen("graph.out", "w", stdout);
	n = read(), m = read(), k = read();
	for(int i = 1; i <= n; ++i)
		for(int j = 1; j <= m; ++j)
			c[i][j] = read();
	for(int i = 1; i <= n; ++i)
		for(int j = 1; j <= m; ++j)
			a[i][j] = read();
	for(int i = 1; i <= n; ++i)
		for(int j = 1; j <= m; ++j)
			if(c[i][j] != -1) solve(i, j, 1);
	printf("%lld\n", ans);
//	fclose(stdin);
//	fclose(stdout);
	return 0;
} 

Ⅲ.LYK loves rabbits