Codeforces 1087 E. Vasya and Templates

版权声明:博主写博客也挺不容易,转载当然阔以,记得先吱一声~ https://blog.csdn.net/Cold_Chair/article/details/85269495

传送门.


真的是被细节恶心到了,是不是我的方法太麻烦了?

要直接s’>=a且s’<=b显然是不好做的,因为要同时考虑两个限制。

于是就要睿智,求>=a的最小的s’。

那么这就很水了。

高位要尽可能的相等,如果不行的话,就回溯,找到最右的一个位置,使它有大于a[x]的选择,然后再把后面填最小的了,注意没有用过的字符给它们匹配一下。

Code:

#include<cstdio>
#include<cstring>
#define pr printf
#define fo(i, x, y) for(int i = x; i <= y; i ++)
using namespace std;

const int N = 1e6 + 5;

int T, k, n;
char s[N], a[N], b[N];
int p[26], u[26], c[26];

int main() {
	scanf("%d", &T);
	fo(ii, 1, T) {
		scanf("%d", &k);
		scanf("%s\n%s\n%s", s + 1, a + 1, b + 1);
		n = strlen(s + 1);
		fo(i, 1, n) s[i] -= 'a', a[i] -= 'a', b[i] -= 'a';
		fo(j, 0, k - 1) p[j] = -1, u[j] = -1, c[j] = 0;
		int x = 1;
		for(; x <= n; x ++) {
			c[s[x]] ++;
			if(p[s[x]] == a[x]) continue;
			if(p[s[x]] == -1 && u[a[x]] == -1) {
				p[s[x]] = a[x];
				u[a[x]] = s[x];
				continue;
			}
			break;
		}
		if(x <= n) {
			c[s[x]] --;
			int xx = x;
			for(; x > 0; x --) {
				if(p[s[x]] > a[x]) break;
				if(x != xx) {
					c[s[x]] --;
					p[s[x]] = !c[s[x]] ? -1 : p[s[x]];
					u[a[x]] = !c[s[x]] ? -1 : u[a[x]];
				}
				if(p[s[x]] != -1) continue;
				int ye = -1;
				fo(j, a[x] + 1, k - 1) if(u[j] == -1) {
					ye = j; break;
				}
				if(ye == -1) continue;
				p[s[x]] = ye; u[ye] = s[x];
				break;
			}
			if(x == 0) {
				printf("NO\n"); continue;
			}
			for(x ++; x <= n; x ++) {
				if(p[s[x]] != -1) continue;
				int ye = -1;
				fo(j, 0, k - 1) if(u[j] == -1) {
					ye = j; break;
				}
				p[s[x]] = ye; u[ye] = s[x];
			}
		}
		fo(i, 0, k - 1) if(p[i] == -1) {
			fo(j, 0, k - 1) if(u[j] == -1) {
				p[i] = j; u[j] = i; break;
			}
		}
		int ans = 1;
		fo(i, 1, n) {
			s[i] = p[s[i]];
			if(s[i] < b[i]) break;
			if(s[i] > b[i]) {
				ans = 0; break;
			}
		}
		if(!ans) {
			printf("NO\n");
		} else {
			pr("YES\n");
			fo(i, 0, k - 1) putchar('a' + p[i]);
			putchar('\n');
		}
	}
}

猜你喜欢

转载自blog.csdn.net/Cold_Chair/article/details/85269495
今日推荐