hdu3427 字符串处理

本文解析了Clickomania游戏的消除算法实现,通过DFS深度优先搜索策略验证字符串能否完全消除,并介绍了字符串预处理和状态标记的方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目链接:Clickomania

题目大意:Clickomannia是一款游戏,游戏规则是每次可以消除连续的同色方块,每次消除又会有新的连结,用字符串表示,问你能不能将整个字符串消除完。

算法分析:一道字符串题。我用dfs()过的。可以先将字符串缩减一下,将字符串中连续的部分用一个字符加一个数字来表示,用两个数组保存,加快扫描速度,从前往后扫描,每一个当前字符要么自成一串,构成合法序列,然后判断剩余字符串是否合法,要么和后面某一个相同字符合并,前提是他们中间的得是合法序列,按照这样分类方法直接dfs() + 标记。做这种类似的题,关键在于找到构成这些字符串的规则或叫词法,然后分类搜索+标记,应该能过。不过这题sha崽大牛结题报告说是区间DP,不懂,待看!

 

ContractedBlock.gif ExpandedBlockStart.gif 代码

   
#include < stdio.h >
#include
< string .h >
#define NN 155
char str[NN];
int mark[NN][NN];
int num[NN];
char cha[NN];

int dfs( int l, int r)
{
int i, t;
if (l == r){ /* 如果就剩一种字符,直接判断是相连的个数是否大于1 */
if (num[l] > 1 )
return 1 ;
else
return 0 ;
}
if (mark[l][r] >= 0 )
return mark[l][r];
/* 当前字符和后面的任一个相同字符合并,前提是夹在他们中间的
字符串是合法的
*/
char ch = cha[l];
for (i = l + 1 ; i <= r; i ++ ){
if (cha[i] == ch){
if (mark[l + 1 ][i - 1 ] = dfs(l + 1 , i - 1 )){
t
= mark[i][r];
mark[i][r]
= - 1 ;
num[i]
+= num[l];
mark[i][r]
= dfs(i, r);
num[i]
-= num[l];
if (mark[i][r] == 1 )
{
mark[i][r]
= t;
return 1 ;
}
mark[i][r]
= t;
}
}
}
/* 当前字符是合法的,直接判断后一部分是否合法
即如果x,y都合法,则xy也合法
*/
if (num[l] > 1 && (mark[l + 1 ][r] = dfs(l + 1 , r)))
return 1 ;
return 0 ;
}
int main()
{
int len, time, index, i;
while (scanf( " %s " , str) != EOF){
len
= strlen(str);
if (len == 0 ){
puts(
" solvable " );
continue ;
}

/* 将字符串缩减成两个数组,一个存出现过的字符,另一个存这个字符出现的次数
例ABBBAACC 缩成ABAC 和 1322
*/
time
= 1 ;
index
= 0 ;
for (i = 1 ; i <= len; i ++ ){
if (str[i] != str[i - 1 ]){
cha[index]
= str[i - 1 ];
num[index]
= time;
time
= 1 ;
index
++ ;
}
else
time
++ ;
}
memset(mark,
- 1 , sizeof (mark));
if (dfs( 0 , index - 1 ))
puts(
" solvable " );
else
puts(
" unsolvable " );
}
return 0 ;
}

 附带两组测试数据:

ABBCCBCAACCA

ABBBAACCDDBCCA

answer:

solvable

solvable

 

 

转载于:https://www.cnblogs.com/ylfdrib/archive/2010/07/11/1775163.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值