EOJ:Clickomania

Clickomania

Time Limit: 5000MS Memory Limit: 65536K

Description

Clickomania is a puzzle in which one starts with a rectangular grid of cells of different colours. In each step, a player selects ("clicks") a cell. All connected cells of the same colour as the selected cell (including itself) are removed if the selected cell is connected to at least one other cell of the same colour. The resulting "hole" is filled in by adjacent cells based on some rule, and the object of the game is to remove all cells in the grid.

In this problem, we are interested in the one-dimensional version of the problem. The starting point of the puzzle is a string of colours (each represented by an uppercase letter). At any point, one may select (click) a letter provided that the same letter occurs before or after the one selected. The substring of the same letter containing the selected letter is removed, and the string is shortened to remove the hole created. To solve the puzzle, the player has to remove all letters and obtain the empty string. If the player obtains a non-empty string in which no letter can be selected, then the player loses.

For example, if one starts with the string "ABBAABBAAB", selecting the first "B" gives "AAABBAAB". Next, selecting the last "A" gives "AAABBB". Selecting an "A" followed by a "B" gives the empty string. On the other hand, if one selects the third "B" first, the string "ABBAAAAB" is obtained. One may verify that regardless of the next selections, we obtain either the string "A" or the string "B" in which no letter can be selected. Thus, one must be careful in the sequence of selections chosen in order to solve a puzzle. Furthermore, there are some puzzles that cannot be solved regardless of the choice of selections. For example, "ABBAAAAB" is not a solvable puzzle.

Some facts are known about solvable puzzles:

* The empty string is solvable.
* If x and y are solvable puzzles, so are xy, AxA, and AxAyA for any uppercase letter A.
* All other puzzles not covered by the rules above are unsolvable.

Given a puzzle, your task is to determine whether it can be solved or not.

 

Input

Each case of input is specified by a single line. Each line contains a string of uppercase letters. Each string has at least one but no more than 150 characters. The input is terminated by the end of file.

 

Output

For each input case, print solvable on a single line if there is a sequence of selections that solves the puzzle. Otherwise, print unsolvable on a line.

 

Sample Input

ABBAABBAAB
ABBAAAAB

 

Sample Output

solvable
unsolvable

原题地址:http://www.cn210.com/onlinejudge/problemshow.php?pro_id=245

_____________________________________________________________________________________

题解:

一看题觉得是搜索,深搜宽搜,每次保存下当前字符串。不过一看题目,字符串的长度居然有150,这么长的状态肯定保存不下……

仔细研究题目,发现那几个规则很有用,应该有助于搜索,不过比赛中始终还是没有动这道题。

 

记忆化搜索。根据题目的rule扩展状态。不过EOJ的评测机果然不行,5s的时限我怎么交都是TLE,几位大牛都是卡着时间过的……难道我RP这么不好。

后来又请教了下2s过的大牛。读入时连续的相同字母只存一个,并且保存下相同字母的个数。同时扩展了那几个RULES,将规则中的单个字母A变成连续相同字母就可以了,即A表示连续的相同字母,而不仅仅只是一个字母。

 

 

代码
1 #include<stdio.h>
2 #include<string.h>
3 #include<memory.h>
4  int dp[152][152],i,j,len,count[152];
5  char str[152],temp[152];
6  void dfs(int l,int r)
7 {
8 int i,j;
9 if (dp[l][r]!=0) return;
10 if (l>r)
11 {
12 dp[l][r]=1;
13 return;
14 }
15 if (l==r)
16 {
17 if (count[l]>1)
18 {
19 dp[l][l]=1;
20 return;
21 }
22 else
23 {
24 dp[l][l]=-1;
25 return;
26 }
27 }
28 for (i=l;i<=r-1;i++)
29 {
30 if (dp[l][i]==0) dfs(l,i);
31 if (dp[l][i]==-1) continue;
32 if (dp[i+1][r]==0) dfs(i+1,r);
33 if (dp[l][i]==1&&dp[i+1][r]==1)
34 {
35 dp[l][r]=1;
36 return;
37 }
38 }
39 if (str[l]==str[r]&&r-l>1)
40 {
41 if (dp[l+1][r-1]==0) dfs(l+1,r-1);
42 if (dp[l+1][r-1]==1)
43 {
44 dp[l][r]=1;
45 return;
46 }
47 if (r-l>2)
48 for (i=l+1;i<=r-1;i++)
49 if (str[i]==str[l])
50 {
51 if (dp[l+1][i-1]==0) dfs(l+1,i-1);
52 if (dp[l+1][i-1]==-1) continue;
53 if (dp[i+1][r-1]==0) dfs(i+1,r-1);
54 if (dp[l+1][i-1]==1&&dp[i+1][r-1]==1)
55 {
56 dp[l][r]=1;
57 return;
58 }
59 }
60 }
61 dp[l][r]=-1;
62 }
63  int main()
64 {
65 while (scanf("%s",temp)!=EOF)
66 {
67 len=-1;
68 j=0;
69 for (i=1;i<=strlen(temp);i++)
70 if (temp[i]!=temp[j])
71 {
72 len++;
73 str[len]=temp[j];
74 count[len]=i-j;
75 j=i;
76 }
77 count[len+1]='\0';
78 memset(dp,0,sizeof(dp));
79 dfs(0,len);
80 if (dp[0][len]==1)
81 printf("solvable\n");
82 else printf("unsolvable\n");
83 }
84 return 0;
85 }

 

posted on 2010-08-07 15:58  风也轻云也淡  阅读(228)  评论(0编辑  收藏  举报