• JZOJ 3207.Orthogonal Anagram


    ( ext{Problem})

    给出一个字符串,求经过重新排列的另一个字典序最小的字符串,满足:相同的位置上
    原串与结果串的字符不同。不存在则输出空串。

    ( ext{Solution})

    考虑从第一位开始枚举匹配
    如果这位匹配(即两个都不相同)某个字符后可以判断出剩下的字符能否合法匹配
    那这位就匹配这个字符即可
    如何判断?
    考虑剩下需要匹配的字符个数和还没用的字符个数
    那么就可以建出一个网络流模型
    每个字符拆成两个点
    源点向 (26) 个字符连边,边权为还可用的个数
    (26) 个字符向汇点连边,边权为还需要的个数
    字符间连能匹配的点
    判断是否满流即可

    可以获得 (90pts)

    ( ext{Code})

    #include <cstdio>
    #include <cstring>
    #include <iostream>
    #define re register
    using namespace std;
    
    const int N = 5e4 + 5, M = 70, S = 54, T = 55;
    char s[N];
    int n, tot, h[M], cur[M], dep[M], Q[M], s1[N], s2[N];
    struct edge{int to, nxt, w;}e[M * M];
    inline void add(int x, int y, int z){e[++tot] = edge{y, h[x], z}, h[x] = tot;}
    
    inline int bfs()
    {
    	for(re int i = 0; i <= T; i++) cur[i] = h[i], dep[i] = 0;
    	int head = 0, tail = 1; Q[1] = S, dep[S] = 1;
    	while (head < tail)
    	{
    		int now = Q[++head];
    		for(re int i = h[now]; i; i = e[i].nxt)
    		{
    			int v = e[i].to;
    			if (dep[v] || !e[i].w) continue;
    			dep[v] = dep[now] + 1, Q[++tail] = v;
    		}
    	}
    	return dep[T];
    }
    int dfs(int x, int lim)
    {
    	if (x == T || lim <= 0) return lim;
    	int flow = 0;
    	for(re int i = cur[x]; i; i = e[i].nxt)
    	{
    		cur[x] = i;
    		int v = e[i].to;
    		if (dep[v] != dep[x] + 1 || !e[i].w) continue;
    		int f = dfs(v, min(lim, e[i].w));
    		if (f <= 0) continue;
    		e[i].w -= f, e[i ^ 1].w += f, lim -= f, flow += f;
    		if (lim <= 0) break;
    	}
    	return flow;
    }
    inline int dinic()
    {
    	int res = 0;
    	while (bfs()) res += dfs(S, N);
    	return res;
    }
    
    inline int check(int y, int x)
    {
    	if (!s1[y]) return 0;
    	tot = 1, memset(h, 0, sizeof h);
    	int total = 0;
    	--s1[y], --s2[x];
    	for(re int i = 0; i < 26; i++)
    	{
    		if (s1[i]) add(S, i, s1[i]), add(i, S, 0);
    		if (s2[i]) add(i + 26, T, s2[i]), add(T, i + 26, 0);
    		total += s2[i];
    	}
    	for(re int i = 0; i < 26; i++)
    		for(re int j = 0; j < 26; j++)
    		if (i ^ j) add(i, j + 26, N), add(j + 26, i, 0);
    	int flow = dinic();
    	if (flow >= total) return 1;
    	++s1[y], ++s2[x];
    	return 0;
    }
    
    int main()
    {
    	scanf("%s", s + 1),	n = strlen(s + 1);
    	for(re int i = 1; i <= n; i++) ++s1[s[i] - 'a'], ++s2[s[i] - 'a'];
    	for(re int i = 1; i <= n; i++)
    	{
    		int fl = 0;
    		for(re int j = 0; j < 26; j++)
    		if (j != s[i] - 'a' && check(j, s[i] - 'a'))
    		{
    			printf("%c", j + 'a'), fl = 1;
    			break;
    		}
    		if (!fl) break;
    	}
    }
    

    正解则是加过判断速度
    一个结论:完全匹配的充要条件是 (forall i in sum,f_i+g_i<=length)
    (f,g) 是这个字符可用个数和需要匹配个数,(length) 为总字符数

    ( ext{Code})

    #include <cstdio>
    #include <cstring>
    #include <iostream>
    #define re register
    using namespace std;
    
    const int N = 5e4 + 5;
    char s[N];
    int n, s1[50], s2[50];
    
    inline int check(int y, int x, int len)
    {
    	if (!s1[y]) return 0;
    	--s1[y], --s2[x];
    	int fl = 1;
    	for(re int i = 0; i < 26; i++)
    	if (s1[i] + s2[i] > len){fl = 0; break;}
    	if (fl) return 1;
    	++s1[y], ++s2[x];
    	return 0;
    }
    
    int main()
    {
    	scanf("%s", s + 1),	n = strlen(s + 1);
    	for(re int i = 1; i <= n; i++) ++s1[s[i] - 'a'], ++s2[s[i] - 'a'];
    	for(re int i = 1; i <= n; i++)
    	{
    		int fl = 0;
    		for(re int j = 0; j < 26; j++)
    		if (j != s[i] - 'a' && check(j, s[i] - 'a', n - i))
    		{
    			printf("%c", j + 'a'), fl = 1;
    			break;
    		}
    		if (!fl) break;
    	}
    }
    
  • 相关阅读:
    怎样用ZBrush中的Curves和Insert笔刷创建四肢
    如何利用ZBrush中的DynaMesh创建身体(二)
    如何利用ZBrush中的DynaMesh创建身体(一)
    如何用ZBrush雕刻出栩栩如生的头发(二)
    Fisker大师用ZBrush制作兽人萨尔全过程
    如何用ZBrush雕刻出栩栩如生的头发(一)
    ZBrush中的SubTool工具该怎样使用
    Access denied for user 'Administrator'@'localhost' (using password: YES)
    java.lang.NoClassDefFoundError: org/apache/ibatis/session/SqlSession
    Unable to install breakpoint in
  • 原文地址:https://www.cnblogs.com/leiyuanze/p/15368900.html
Copyright © 2020-2023  润新知