【IndiaHacks 2016 - Online Edition (Div 1 + Div 2) ErrichtoB】【爆搜dfs】 Bear and Compressing 字符串变换前2位变

Bear and Compressing
time limit per test
2 seconds
memory limit per test
256 megabytes
input
standard input
output
standard output

Limak is a little polar bear. Polar bears hate long strings and thus they like to compress them. You should also know that Limak is so young that he knows only first six letters of the English alphabet: 'a', 'b', 'c', 'd', 'e' and 'f'.

You are given a set of q possible operations. Limak can perform them in any order, any operation may be applied any number of times. The i-th operation is described by a string ai of length two and a string bi of length one. No two of q possible operations have the same string ai.

When Limak has a string s he can perform the i-th operation on s if the first two letters of s match a two-letter string ai. Performing the i-th operation removes first two letters of s and inserts there a string bi. See the notes section for further clarification.

You may note that performing an operation decreases the length of a string s exactly by 1. Also, for some sets of operations there may be a string that cannot be compressed any further, because the first two letters don't match any ai.

Limak wants to start with a string of length n and perform n - 1 operations to finally get a one-letter string "a". In how many ways can he choose the starting string to be able to get "a"? Remember that Limak can use only letters he knows.

Input

The first line contains two integers n and q (2 ≤ n ≤ 61 ≤ q ≤ 36) — the length of the initial string and the number of available operations.

The next q lines describe the possible operations. The i-th of them contains two strings ai and bi (|ai| = 2, |bi| = 1). It's guaranteed thatai ≠ aj for i ≠ j and that all ai and bi consist of only first six lowercase English letters.

Output

Print the number of strings of length n that Limak will be able to transform to string "a" by applying only operations given in the input.

Examples
input
3 5
ab a
cc c
ca a
ee c
ff d
output
4
input
2 8
af e
dc d
cc f
bc b
da b
eb a
bb b
ff c
output
1
input
6 2
bb a
ba a
output
0
Note

In the first sample, we count initial strings of length 3 from which Limak can get a required string "a". There are 4 such strings: "abb", "cab", "cca", "eea". The first one Limak can compress using operation 1 two times (changing "ab" to a single "a"). The first operation would change "abb" to "ab" and the second operation would change "ab" to "a".

Other three strings may be compressed as follows:

  • "cab "ab "a"
  • "cca "ca "a"
  • "eea "ca "a"

In the second sample, the only correct initial string is "eb" because it can be immediately compressed to "a".

#include<stdio.h>
#include<iostream>
#include<string.h>
#include<string>
#include<ctype.h>
#include<math.h>
#include<set>
#include<map>
#include<vector>
#include<queue>
#include<bitset>
#include<algorithm>
#include<time.h>
using namespace std;
void fre() { freopen("c://test//input.in", "r", stdin); freopen("c://test//output.out", "w", stdout); }
#define MS(x,y) memset(x,y,sizeof(x))
#define MC(x,y) memcpy(x,y,sizeof(x))
#define MP(x,y) make_pair(x,y)
#define ls o<<1
#define rs o<<1|1
typedef long long LL;
typedef unsigned long long UL;
typedef unsigned int UI;
template <class T1, class T2>inline void gmax(T1 &a, T2 b) { if (b>a)a = b; }
template <class T1, class T2>inline void gmin(T1 &a, T2 b) { if (b<a)a = b; }
const int N = 0, M = 0, Z = 1e9 + 7, ms63 = 0x3f3f3f3f;
int n, m;
char s[10];
char t[10];
int mp[128 * 128];
int ans;
void dfs(int p)
{
	if (p == n)
	{
		MC(t, s);
		for (int i = 1; i < n; ++i)
		{
			int v = t[i - 1] * 128 + t[i];
			if (mp[v] == 0)return;
			t[i] = mp[v];
		}
		if (t[n - 1] == 'a')++ans;
		return;
	}
	for (int i = 'a'; i <= 'f'; ++i)
	{
		s[p] = i;
		dfs(p + 1);
	}
}
char a[4], b[4];
int main()
{
	while (~scanf("%d%d", &n,&m))
	{
		MS(mp, 0);
		for (int i = 1; i <= m; ++i)
		{
			scanf("%s%s", a, b);
			mp[a[0] * 128 + a[1]] = b[0];
		}
		ans = 0;
		dfs(0);
		printf("%d\n", ans);
	}
	return 0;
}
/*
【题意】
给你一个长度为n(6)的字符串,字符集为'a'~'f'
我们有m(36)种变换序列a[i],b[i],
对于第i种变换序列,可以把字符串的开头前两位,
由长度为2的a[i](如果是)变为长度的为1的b[i]。
问你是否可以把这个字符串变换成'a'

【类型】
爆搜

【分析】
方法一:
因为长度最多为6,字符集也很小。
所以一共的可能性其实也只有6^6种,
于是我们爆搜这个字符串,然后暴力链变换即可。

方法二:
我们可以从'a'出发,倒着来由长度为1向长度为2拓展。
复杂度比方法一优秀一些。

【时间复杂度&&优化】
O(n^6 * low)

*/


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值