JZOJ 3207.Orthogonal Anagram
\(\text{Problem}\)
给出一个字符串,求经过重新排列的另一个字典序最小的字符串,满足:相同的位置上
原串与结果串的字符不同。不存在则输出空串。
\(\text{Solution}\)
考虑从第一位开始枚举匹配
如果这位匹配(即两个都不相同)某个字符后可以判断出剩下的字符能否合法匹配
那这位就匹配这个字符即可
如何判断?
考虑剩下需要匹配的字符个数和还没用的字符个数
那么就可以建出一个网络流模型
每个字符拆成两个点
源点向 \(26\) 个字符连边,边权为还可用的个数
\(26\) 个字符向汇点连边,边权为还需要的个数
字符间连能匹配的点
判断是否满流即可
可以获得 \(90pts\)
\(\text{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\) 为总字符数
\(\text{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;
}
}
JZOJ 3207.Orthogonal Anagram的更多相关文章
- bzoj AC倒序
Search GO 说明:输入题号直接进入相应题目,如需搜索含数字的题目,请在关键词前加单引号 Problem ID Title Source AC Submit Y 1000 A+B Problem ...
- [LeetCode] Valid Anagram 验证变位词
Given two strings s and t, write a function to determine if t is an anagram of s. For example, s = & ...
- Leetcode Valid Anagram
Given two strings s and t, write a function to determine if t is an anagram of s. For example,s = &q ...
- LeetCode 242 Valid Anagram
Problem: Given two strings s and t, write a function to determine if t is an anagram of s. For examp ...
- 【POJ】3207 Ikki's Story IV - Panda's Trick
http://poj.org/problem?id=3207 题意:一个圆上顺时针依次排列着标号为1-n的点,这些点之间共有m条边相连,每两个点只能在圆内或者圆外连边.问是否存在这些边不相交的方案.( ...
- 【09_242】Valid Anagram
Valid Anagram My Submissions Question Total Accepted: 43694 Total Submissions: 111615 Difficulty: Ea ...
- 【leetcode❤python】242. Valid Anagram
class Solution(object): def isAnagram(self, s, t): if sorted(list(s.lower()))==sorted(list ...
- 242. Valid Anagram
Given two strings s and t, write a function to determine if t is an anagram of s. For example,s = &q ...
- (easy)LeetCode 242.Valid Anagram
Given two strings s and t, write a function to determine if t is an anagram of s. For example,s = &q ...
- 【BZOJ】【3207】花神的嘲讽计划 I
字符串Hash+可持久化线段树 好神奇的转化…… 蒟蒻一开始还去想AC自动机去了……然而由于a[i]的范围是小于等于n,怎么也想不出一个时间复杂度合理的方法 膜拜了题解0.0原来是字符串Hash! 首 ...
随机推荐
- ValueError: Detected newline in header value. This is a potential security problem
原因 flask框架进行重定向的url中包含 换行符\n或\r 解决方法 使用 strip() 函数去除行首或行尾的换行符(如果你url中间包含这些符号replace函数替换, 但是如果中间包含只能说 ...
- jmeter 从多个数中随机取一个值的方法
问题描述:使用jmeter进行接口测试时,遇到枚举值(如:10代表闲置.15代表使用中.20代表维修等)我们需要随机取一个类型传到接口中. 解决思路:通过函数助手查找随机函数,找到__chooseRa ...
- 2022-6.824-Lab1:Map&Reduce
lab 地址 : https://pdos.csail.mit.edu/6.824/labs/lab-mr.html 1. 介绍 准备工作 阅读 MapReduce 做什么 实现一个分布式的 Map ...
- 「Docker学习系列教程」9-Docker容器数据卷介绍
通过前面8篇文章的学习,我们已经学会了docker的安装.docker常用的命令已经docker镜像修改后提交的远程镜像仓库及提交到公司的私服仓库中.接下来,我们再来学学Docker另外一个重要的东西 ...
- java时区相关问题(被恶心到了)
在项目开发中,遇到了mysql5.7数据库相关的时区问题.整理如下: 问题一:在使用swagger测试接口时,数据库记录的时间和输入的不一致.如下图: swagger中输入的是:"recei ...
- python语法之注释
引言 注释的最大作用是提高程序的可读性,在开发过程中非常有必要加上注释.Python 支持两种类型的注释,分别是单行注释和多行注释. 1 单行注释 Python 使用井号#作为单行注释的符号,语法格式 ...
- 同步异步、mutiprocessing创建进程process模块及进程对象的多种方法、消息队列Queue
目录 同步异步 阻塞与非阻塞 综合使用 创建进程的多种方式之multiprocess.process模块 进程间数据隔离 进程的join方法 IPC机制 生产者 消费者模型 进程对象的多种方法 守护进 ...
- uniapp详细入门教程
链接:https://www.ruletree.club/archives/2071/ 点击链接查看,内容详细,一学就会哦~! /******** * * .-~~~~~~~~~-._ _.-~~~~ ...
- 痞子衡嵌入式:探讨i.MXRT下FlexSPI driver实现Flash编程时对于中断支持问题
大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家介绍的是i.MXRT下FlexSPI driver实现Flash编程时对于中断支持问题. 前段时间有客户在官方社区反映 i.MXRT1170 下 ...
- Java开发学习(五十)----MyBatisPlus快速开发之代码生成器解析
1.代码生成器原理分析 造句: 我们可以往空白内容进行填词造句,比如: 在比如: 观察我们之前写的代码,会发现其中也会有很多重复内容,比如: 那我们就想,如果我想做一个Book模块的开发,是不是只需要 ...