HRBUST2030(dfs)

成语接龙

Time Limit: 1000 MS Memory Limit: 32768 KB

64-bit integer IO format: %lld , %llu Java class name: Main

[Submit] [Status]
[Discuss]

题目链接:http://acm.hrbust.edu.cn/vj/index.php?c=problem-problem&id=131971

Description

给出N个成语,通过成语接龙,求接出最长龙的成语个数。

每个成语由至少三个至多8个汉字组成,如果前一个成语的最后一个字和后一个成语的第一个字相同,那么就可以接到一起。

为了将问题简化,每个汉字用4个字母编码代替。保证每个汉字的都有唯一的编码。所有字母均为小写字母,且以第一个成语为开始成语, 每个成语只可以使用一次。

Input

多组测试数据,对每组数据

第一行是一个整数N,代表有N个成语。

接下来N行,每行一个成语。

(N <= 20)

Output

输出最长长度

Sample Input

5
adfkejimejlsgkeh
emiemkwlcuhelmge
gkeheohowehiemie
lmgejoewijfeabcd
emiekejlwejdadfk

Sample Output

4


解题思路:
	这道题读题是个坎·····首先注意要存的是每个字符串的前4个字母和后四个字母,然后要注意每次接龙都是以第一个成语为开始。
	读题过后,就可以开始考虑求解了。题目要求输出最长长度,很明显会出现第一个单词取完取第三个单词,然后发现此时我可以连第二个单词这种情况,这就是一种回溯。所以以第一个单词为起点,用dfs把n-1个串搜一遍。
	这里又从LSJ那里学到一个好思想,把它想象成一棵树,最后求最深的高度。每次搜索时用vis做个标记,两个原则:(1)标记过的我不走(2)和当前key值相同的点我不走。
	每次更新max_cnt。注意递归时++step和1+step的区别。如果写成++step,那么会改变step的值,同层的节点高度会改变;反之,如果是1+step,那么step值不会变,当扫完一个节点后,可以按原来的step值访问同层的其他节点。

完整代码:
#include <functional>
#include <algorithm>
#include <iostream>
#include <fstream>
#include <sstream>
#include <iomanip>
#include <numeric>
#include <cstring>
#include <climits>
#include <cassert>
#include <complex>
#include <cstdio>
#include <string>
#include <vector>
#include <bitset>
#include <queue>
#include <stack>
#include <cmath>
#include <ctime>
#include <list>
#include <set>
#include <map>
using namespace std;

#pragma comment(linker, "/STACK:102400000,102400000")

typedef long long LL;
typedef double DB;
typedef unsigned uint;
typedef unsigned long long uLL;

/** Constant List .. **/ //{

const int MOD = int(1e9)+7;
const int INF = 0x3f3f3f3f;
const LL INFF = 0x3f3f3f3f3f3f3f3fLL;
const DB EPS = 1e-9;
const DB OO = 1e20;
const DB PI = acos(-1.0); //M_PI;
string str;
int n;
int vis[100001];
struct node
{
    string start;
    string ends;
}q[100001];
int max_cnt;
int dfs(int key , int step , int &max_cnt)
{

    for(int i = 0 ; i < n ; i ++)
    {
        if(vis[i] == 0 && i != key)
        {
            if(q[key].ends == q[i].start)
            {
                vis[i] = 1;
                int t = dfs(i , 1+step , max_cnt);
                vis[i] = 0;
                max_cnt = max(max_cnt , t);
            }
        }
    }
    return step;
}

int main()
{
    #ifdef DoubleQ
    freopen("in.txt","r",stdin);
    #endif

    while(~scanf("%d",&n))
    {

        for(int i = 0 ; i < n ; i ++)
        {
            cin >> str ;
            int len  = str.length();
            q[i].start = "";
            q[i].start += str[0];
            q[i].start += str[1];
            q[i].start += str[2];
            q[i].start += str[3];

            q[i].ends = "";
            q[i].ends += str[len-4];
            q[i].ends += str[len-3];
            q[i].ends += str[len-2];
            q[i].ends += str[len-1];

        }
        memset(vis , 0 , sizeof(vis));
        max_cnt = 0;
        vis[0] = 1;
        int step = 0;
        dfs(max_cnt , step , max_cnt);
        printf("%d\n",max_cnt+1);
    }
}

时间: 2024-10-04 02:05:11

HRBUST2030(dfs)的相关文章

POJ 3087 Shuffle&#39;m Up (DFS)

题目链接:Shuffle'm Up 题意:有a和b两个长度为n的字符序列,现定义操作: 将a.b的字符交叉合并到一个序列c,再将c最上面的n个归为a,最下面n个归为b 给出a,b和目标序列c,问最少多少次操作a.b转化为c 解析:将a.b放入哈希表,然后模拟操作过程直接dfs即可. AC代码: #include <cstdio> #include <iostream> #include <cstring> #include <map> using names

LeetCode Subsets (DFS)

题意: 给一个集合,有n个互不相同的元素,求出所有的子集(包括空集,但是不能重复). 思路: DFS方法:由于集合中的元素是不可能出现相同的,所以不用解决相同的元素而导致重复统计. 1 class Solution { 2 public: 3 vector<vector<int>> subsets(vector<int>& nums) { 4 sort(nums.begin(),nums.end()); 5 DFS(0,nums,tmp); 6 return a

POJ 1699 Best Sequence(DFS)

題目鏈接 題意 : 將幾個片段如圖所示方法縮成一個序列,求出最短這個序列. 思路 : 其實我也不知道怎麼做.....看網上都用了DP.....但是我不會.....這個DP不錯,還有用KMP+状压DP做的 1 //1699 2 #include <iostream> 3 #include <stdio.h> 4 #include <string.h> 5 #include <string> 6 7 using namespace std; 8 9 string

LeetCode Subsets II (DFS)

题意: 给一个集合,有n个可能相同的元素,求出所有的子集(包括空集,但是不能重复). 思路: 看这个就差不多了.LEETCODE SUBSETS (DFS) 1 class Solution { 2 public: 3 vector<vector<int>> subsets(vector<int>& nums) { 4 sort(nums.begin(),nums.end()); 5 DFS(0,nums,tmp); 6 ans.push_back(vector

poj A Knight&#39;s Journey(DFS)

题目链接:http://acm.hrbust.edu.cn/vj/index.php?c=problem-problem&id=190592 题意:给出p*q的棋盘,从(A,1)开始,走“日”字,问能否走完棋盘上所有的点,如果能,按字典序输出路径: 思路:DFS,并保存路径即可,注意处理走的方向顺序int dir[8][2]={{-2,-1},{-2,1},{-1,-2},{-1,2},{1,-2},{1,2},{2,-1},{2,1}}; #include <stdio.h> #in

11218 - KTV(dfs)

问题 C: Repeat Number 时间限制: 1 Sec  内存限制: 128 MB 提交: 23  解决: 7 [提交][状态][论坛] 题目描述 Definition: a+b = c, if all the digits of c are same ( c is more than ten),then we call a and b are Repeat Number. My question is How many Repeat Numbers in [x,y]. 输入 There

POJ 2488-A Knight&#39;s Journey(DFS)

A Knight's Journey Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 31702   Accepted: 10813 Description Background The knight is getting bored of seeing the same black and white squares again and again and has decided to make a journey ar

poj3187Backward Digit Sums(DFS)

题目链接: huangjing 思路: 这个题目想到dfs很容易,但是纠结在这么像杨辉三角一样计算那些值,这个我看的队友的,简直厉害,用递归计算出杨辉三角顶端的值....具体实现详见代码... 题目: Language: Default Backward Digit Sums Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 4285   Accepted: 2474 Description FJ and his cows

A Knight&#39;s Journey (DFS)

Background The knight is getting bored of seeing the same black and white squares again and again and has decided to make a journey around the world. Whenever a knight moves, it is two squares in one direction and one square perpendicular to this. Th