(简单)搜索 HOJ 1070 Word

来源:互联网 发布:网络购票岫岩到沈阳 编辑:程序博客网 时间:2024/05/28 15:07

Word

My Tags  (Edit)
Source : ACM ICPC Central European Regional 1997Time limit : 1 secMemory limit : 32 M

Submitted : 114, Accepted : 46

Dr. R. E. Wright's class was studying modified L-Systems. Let us explain necessary details. As a model let us have words of length n over a two letter alphabet {a, b}. The words are cyclic, this means we can write one word in any of n forms we receive by cyclic shift, whereby the first and the last letters in the word are considered to be neighbours.

Rewriting rules rewrite a letter at a position i, depending on letters at the positions i - 2, i, i+1. We rewrite all letters of the word in one step. When we have a given starting word and a set of rewriting rules a natural question is: how does the word look after s rewriting steps?

Help Dr. R. E. Wright and write a program which solves this task.


Input 


There are several blocks in the input, each describing one system. There is an integer number n, 2 < n < 16 the length of the input word in the first line. There is a word in the next line. The word contains only lowercase letters a and b. There are four characters c1 c2 c3 c4 in the next eight lines. Each quadruple represents one rewriting rule with the following meaning: when the letter at the position i - 2 is c1 and the letter at the position i is c2 and the letter at the position i + 1 is c3 then the letter at the position i after rewriting will be c4. Rewriting rules are correct and complete. There is an integer number s, 0 <= s <= 2000000000, in the last line of the block.


Output 

There is one line corresponding to each block of the input. The line contains a word which we receive after s rewriting steps from the corresponding starting word using given rewriting rules. As we mentioned above, the word can be written in any of n cyclic shifted forms. The output file contains the lexicographically smallest word, assuming that a < b.


Sample Input

5aaaaaaaabaabbabababbbbaabbabbbbabbbbb1


Sample Output

bbbbb
题意:给出一串只有a和b的字符串,这个字符串是首尾相连的,同时给出如果位置为i-2为c1位置i为c2位置i+1为c3时,进行变换的话,位置i会变成c4, 每一步变换是根据该串目前的情况直接把这整个串进行改变,然后输入一个s次变换,求最终变换得到的串的序列,要求最小的(a<b)

思路: s非常大,2x10^9  不可能一步一步的来啦。 我们注意到n<16  那么对于一个串来讲最多只有2^15中情况,也就是说如果变换的次数超过2^15次方,肯定会回到之前出现过的状态,那么这里就是一个环,那么就可以根据环的大小,环的起始位置,以及要求的变换次数,得出最终的位置。我们用一个状态数组记录得到某一个状态的第一步是多少,然后再用一个数组记录第几步是什么状态,那么当出现环的时候就很快能输出答案了,输出答案的时候要求输出最小的,于是我们分别把每一个位置作为头的串是什么都分出来,然后排一下序就行了

代码:
#include<iostream>
#include<cstdio>
#include<string.h>
#include<algorithm>
#include<string>
#include<deque>
#include<queue>
#include<math.h>
#include<vector>
using namespace std;
#define MAX (1<<16)+10
#define MOD 99997
const int inf = 0xfffffff;

int State[MAX];
int Index[MAX];

int zero_one[20];
int oper[20];
int tem[20];
char ans[20][20];

int n;
int getState()
{
int ret = 0;
for (int i = 0 ; i < n ; ++i)
ret += (zero_one[i]<<i);
return ret;
}

void changeState()
{
int state;
for (int i = 0 ; i < n ; ++i)
{
state = (zero_one[i]<<1)+(zero_one[(i-2+n)%n]<<0)+(zero_one[(i+1)%n]<<2);
tem[i] = oper[state];
}
for (int i = 0 ; i < n;  ++i)
zero_one[i] = tem[i];
}


int cmp(const void* s1, const void*s2)
{
return strcmp((char*)s1,(char*)s2);
}

void output(int state)
{
for (int i = 0 ; i < n;  ++i)
{
if (state&(1<<i)) ans[0][i] = 'b';
else ans[0][i] = 'a';
}
ans[0][n] = 0;
for (int i = 1 ; i < n ; ++i)
{
strcpy(ans[i],ans[i-1]+1);
ans[i][n-1] = ans[i-1][0];
ans[i][n] = 0;
}

qsort(ans,n,sizeof(ans[0]),cmp);
printf("%s\n",ans[0]);
}
int main()
{
while (scanf("%d",&n)==1)
{
char buffer[100];
scanf("%s",buffer);
for (int i = 0 ; i < n ; ++i)
zero_one[i] = buffer[i]-'a';

memset(State,-1,sizeof(State));
memset(Index,-1,sizeof(Index));
State[getState()] = 0;
Index[0] = getState();
for (int i = 0 ; i < 8 ; ++i)
{
int state = 0;
scanf("%s",buffer);
state += (buffer[0]-'a')<<0;
state += (buffer[1]-'a')<<1;
state += (buffer[2]-'a')<<2;
oper[state] = buffer[3]-'a';
}
int s;
scanf("%d",&s);
int tem;
bool flag = true;
for (int i = 1 ; i <= s ; ++i)
{
changeState();
if (State[tem = getState()]==-1)
{
Index[i] = tem;
State[tem] = i;
}
else 
{
flag = false;

output(Index[(s-State[tem])%(i-State[tem])+State[tem]]);
break;
}
}
if (flag)
output(getState());
}
}
0 0
原创粉丝点击