Impossible Game
题目描述
你发明了一个简单的单人电脑游戏。在开始游戏时,玩家必须输入一个长度为 K 的字
符串,且这个字符串的元素只能为‘A’‘B’‘C’或者‘D’。每一种字符串都代表一种颜色,
不同的字符串可能有相同的颜色,而一种字符串的颜色是由你在游戏开始前决定的。为了赢
得这个游戏,玩家必须经过一系列操作,将起始输入的字符串转换成另一个字符串,且两个
字符串所代表的颜色相同但构成不同。游戏规定了 N 种置换规则,每种规则由两个长度相
同的字符串 a[i]和 b[i]表示,且 a[i]和 b[i] 也均由‘A’‘B’‘C’或者‘D’构成。玩家
可以进行下列两种操作:
1、 交换当前字符串中两个相邻字符。例如:你可以将子串 ABC->ACB。
2、 如果当前字符串中的某个子串恰为 a[i],那么玩家可以将其置换为 b[i]。例如:
置换规则为 ABC->BCD,那么你可以将子串 CABC->CBCD。
请问最少需要多少种不同的颜色,才能让玩家无论如何操作均不能赢得游戏。
输入格式
第一行两个整数,K 和 N。
接下来 N 行,每行一个字符串表示 a[i]。
接下来 N 行,每行一个字符串表示 b[i]。
输出格式
输出一个整数,表示最少需要多少种不同的颜色使得玩家必败。
样例输入
2 2
CA
BC
AD
AC
样例输出
6
数据范围与约定
对于 30%的数据,满足 1<=N<=8。
对于 100%的数据,满足 1<=N<=50,1<=K<=30,1<=length of a[i]=length of
b[i]<=K。

题解:

首先有一个显然的结论:两个字符串如果每个字母的个数都一样,那么肯定可以通过1操作互相转化

那么我们就用一个四元组来表示一类字符串,具体可以用当成32进制的数存储,

当然这样的字符串个数并不都一样,可以通过组合数算出来,v[i]表示字符组成为 i 的字符串的个数

那么如果 i 能够 通过 2操作转化到 j ,就连一条有向边(i,j)

得到一个有向图,可能有环,那么tarjan缩点,一个scc的权值为内部所有点的权值之和

重新构图之后,也就是求一条“最长链”,可以拓扑排序+topsort解决

ps:要注意重构图的时候边集数组,tot,head数组,insert操作不能与第一次的混了

代码:

 type node=record
go,next:longint;
end;
var le,ri:array[..,..] of longint;
a,b:array[..] of string;
e,e2:array[..] of node;
c:array[..,..] of int64;
dfn,low,w,ww,www:array[..] of int64;
head,head2,sta,scc,q,inp:array[..] of longint;
i,j,k,l,p,tot,cnt,n,m,h,t,x,y:longint;
tmp1,tmp2,ans,ti,top:int64;
num:array[..,..,..] of int64;
function min(x,y:int64):int64;
begin
if x<y then exit(x) else exit(y);
end;
function max(x,y:int64):int64;
begin
if x>y then exit(x) else exit(y);
end; procedure insert(x,y:longint);
begin
inc(tot);
e[tot].go:=y;e[tot].next:=head[x];head[x]:=tot;
end;
procedure insert2(x,y:longint);
begin
inc(tot);
e2[tot].go:=y;e2[tot].next:=head2[x];head2[x]:=tot;
end;
function jz(x,y,z:longint):int64;
begin
jz:=x*(n+)*(n+)+y*(n+)+z;
end;
procedure init;
begin
readln(n,m);
fillchar(x,sizeof(x),);
fillchar(y,sizeof(y),);
for i:= to m do readln(a[i]);
for i:= to m do readln(b[i]);
for i:= to m do
for j:= to length(a[i]) do
begin
inc(le[i,ord(a[i][j])-ord('A')+]);
inc(ri[i,ord(b[i][j])-ord('A')+]);
end;
end;
procedure zuhe;
begin
c[,]:=;
for i:= to do
begin
c[i,]:=;c[i,i]:=;
for j:= to i- do
c[i,j]:=c[i-,j-]+c[i-,j];
end;
end;
procedure prepare;
begin
for i:= to n do
for j:= to n do
for k:= to n do
begin
l:=n-i-j-k;if l< then continue;
tmp1:=jz(i,j,k);
tmp2:=c[n,i]*c[n-i,j]*c[n-i-j,k];
num[i,j,k]:=tmp1;
w[tmp1]:=tmp2;
end;
for i:= to n do
for j:= to n do
for k:= to n do
begin
l:=n-i-j-k;if l< then continue;
for p:= to m do
if (i>=le[p,]) and (j>=le[p,]) and (k>=le[p,]) and (l>=le[p,])
then insert(num[i,j,k],num[i-le[p,]+ri[p,],j-le[p,]+ri[p,],k-le[p,]+ri[p,]]);
end;
end;
procedure dfs(u:longint);
var i,v,x:longint;
begin
inc(ti);dfn[u]:=ti;low[u]:=ti;
inc(top);sta[top]:=u;
i:=head[u];
while i<> do
begin
v:=e[i].go;
if dfn[v]= then
begin
dfs(v);
low[u]:=min(low[u],low[v]);
end
else
if scc[v]= then low[u]:=min(low[u],dfn[v]);
i:=e[i].next;
end;
if low[u]=dfn[u] then
begin
inc(cnt);
repeat
x:=sta[top];dec(top);
scc[x]:=cnt;
inc(ww[cnt],w[x]);
if x=u then break;
until false;
end;
end;
procedure tarjan;
begin
top:=;
fillchar(dfn,sizeof(dfn),);
ti:=;cnt:=;
for i:= to (n+)*(n+)*(n+) do
if w[i]<> then
begin
if dfn[i]= then dfs(i);
end;
end;
procedure topsort;
begin
fillchar(inp,sizeof(inp),);
for x:= to (n+)*(n+)*(n+) do
begin
i:=head[x];
while i<> do
begin
y:=e[i].go;
if scc[x]<>scc[y] then
begin
inc(inp[scc[y]]);insert2(scc[x],scc[y]);
end;
i:=e[i].next;
end;
end;
h:=;t:=;www:=ww;
for i:= to cnt do if inp[i]= then begin inc(t);q[t]:=i;end;
while h<t do
begin
inc(h);
x:=q[h];
i:=head2[x];
while i<> do
begin
y:=e2[i].go;
dec(inp[y]);if inp[y]= then begin inc(t);q[t]:=y;end;
www[y]:=max(www[y],www[x]+ww[y]);
i:=e2[i].next;
end;
end;
end;
procedure getans;
begin
ans:=;
for i:= to cnt do ans:=max(ans,www[i]);
writeln(ans);
end;
begin
assign(input,'game.in');assign(output,'game.out');
reset(input);rewrite(output);
init;
zuhe;
prepare;
tarjan;
topsort;
getans;
close(input);close(output);
end.

20140708郑州培训第二题Impossible Game的更多相关文章

  1. 05:统计单词数【NOIP2011复赛普及组第二题】

    05:统计单词数 总时间限制:  1000ms 内存限制:  65536kB 描述 一般的文本编辑器都有查找单词的功能,该功能可以快速定位特定单词在文章中的位置,有的还能统计出特定单词在文章中出现的次 ...

  2. 常见面试第二题之什么是Context

    今天的面试题,也就是我们常见面试题系列的第二题,我们来讲一讲android中的context.我相信大家android开发者一定对于这个context非常熟悉,肯定都有使用过,肯定没有没使用过的.但是 ...

  3. 《学习OpenCV》练习题第五章第二题abc

    代码: #include <stdio.h> #include <opencv/highgui.h> #include <opencv/cv.h> #include ...

  4. 《学习OpenCV》练习题第四章第二题

    #include <highgui.h> #include <cv.h> #pragma comment (lib,"opencv_calib3d231d.lib&q ...

  5. CSDN挑战编程——《金色十月线上编程比赛第二题:解密》

    金色十月线上编程比赛第二题:解密 题目详情: 小强是一名学生, 同一时候他也是一个黑客. 考试结束后不久.他吃惊的发现自己的高等数学科目竟然挂了,于是他果断入侵了学校教务部站点. 在入侵的过程中.他发 ...

  6. NOIP2005-普及组复赛-第二题-校门外的树

    题目描述 Description 某校大门外长度为L的马路上有一排树,每两棵相邻的树之间的间隔都是1米.我们可以把马路看成一个数轴,马路的一端在数轴0的位置,另一端在L的位置:数轴上的每个整数点,即0 ...

  7. 【gdoi2018 day2】第二题 滑稽子图(subgraph)(性质DP+多项式)

    题目大意 [gdoi2018 day2]第二题 滑稽子图(subgraph) 给你一颗树\(T\),以及一个常数\(K\),对于\(T\)的点集\(V\)的子集\(S\). 定义\(f(S)\)为点集 ...

  8. 【LOJ#6066】「2017 山东一轮集训 Day3」第二题(哈希,二分)

    [LOJ#6066]「2017 山东一轮集训 Day3」第二题(哈希,二分) 题面 LOJ 题解 要哈希是很显然的,那么就考虑哈希什么... 要找一个东西可以表示一棵树,所以我们找到了括号序列. 那么 ...

  9. test20181020 B君的第二题

    题意 分析 考场70分 一看就是裸的kmp,直接打上去. #include<cstdlib> #include<cstdio> #include<cmath> #i ...

随机推荐

  1. KP 佛学禅语

    1.人之所以痛苦,在于追求错误的东西. 2.如果你不给自己烦恼,别人也永远不可能给你烦恼.因为你自己的内心,你放不下. 3.你永远要感谢给你逆境的众生. 4.你永远要宽恕众生,不论他有多坏,甚至他伤害 ...

  2. 如何使用SC命令添加删除服务

    1.如何删除服务 cmd然后再输入 sc delete "服务名称" 后,回车,双引号必须为英文符号. 2.添加服务 sc create ServiceName binPath= ...

  3. C/C++随机数rand()和种子函数srand()

    在计算机编程中,常常要产生一个随机数.但是要让计算机产生一个随机数并不那么容易.计算机的执行,是以代码来进行的,所以并不可能像抽牌,扔骰子那样产生一个真正具有随机意义的数.只可能以一定的算法产生一个伪 ...

  4. Codevs 1904 最小路径覆盖问题

    1904 最小路径覆盖问题 时间限制: 2 s 空间限制: 256000 KB 题目等级 : 大师 Master 传送门 题目描述 Description 给定有向图G=(V,E).设P 是G 的一个 ...

  5. JVM - 内存溢出问题排查相关命令jcmd jmap

    jcmd http://docs.oracle.com/javase/8/docs/technotes/tools/windows/jcmd.html jcmd-l  列出正在执行的JAVA进程ID ...

  6. 开发错误日志之Unix/Linux命令未执行或无结果等且程序无错误

    在Unix/Linux环境中开发时,特别要注意权限问题,否则经常找不到错误的原因,其实就是因为权限所致.

  7. Asp.net创建伪静态页面

    下面是我研究了好几天和同事一起才研究出来的,原创. 1伪静态的定义: 伪静态是相对真实静态来讲的,通常我们为了增强搜索引擎的友好面,都将文章内容生成静态页面,但是有的朋友为了实时的显示一些信息.或者还 ...

  8. markdown与textile之间互相转换

    markdown与textile之间互相转换 redmine中默认使用的是textile那么从别的地方复制过来的markdown格式的内容需要进行转换 找到一款工具叫做pandoc http://jo ...

  9. document.getElementById获取不到标签值

    var apliay=document.getElementById('apliay_ok'); 代码里指定有id="apliay_ok"的标签,但是获取不到,折腾半天原来是因为在 ...

  10. Python使用re实现计算器

    re 正则表达式 计算器 海瑞博客-学习python之路•2016-12-01•Python• 59•0•A+ A- re是一门小型语言 元字符 .      通配符除了\n ^     以什么开始的 ...