UVALive 2403 77377解题报告(深搜)

  题意:给你一些固定的字符串,在给出数字,根据键盘的对应关系,输出所有的满足条件的字符串,输出顺序无所谓。

  思路:因为题目说了,输出比较小,说明测试数据并不强,所以可以暴力回溯求出答案,将所有的给出的字符串压缩为数字,再将对应相同数字的字符串存储起来(当时忘了这里,WA了几次),然后深搜即可。

  注意:多个字符串有可能对应相同的数字,需要另外存储,在深搜的时候,枚举这个符合条件的字符串。

代码如下:

#include<iostream>
#include<cstdio>
#include<vector>
#include<cstring>
#include<map>
#include<cmath>
using namespace std;
map<string,int>ma;
vector<int> ve[150];
char get_num(char ch){
    if(ch>=‘a‘&&ch<=‘c‘) return ‘2‘;
    if(ch>=‘d‘&&ch<=‘f‘) return ‘3‘;
    if(ch>=‘g‘&&ch<=‘i‘) return ‘4‘;
    if(ch>=‘j‘&&ch<=‘l‘) return ‘5‘;
    if(ch>=‘m‘&&ch<=‘o‘) return ‘6‘;
    if(ch>=‘p‘&&ch<=‘s‘) return ‘7‘;
    if(ch>=‘t‘&&ch<=‘v‘) return ‘8‘;
    if(ch>=‘w‘&&ch<=‘z‘) return ‘9‘;
}
string change(string a){
    int len = a.length();
    string tmp = "";
    for(int i = 0;i < len;i++){
        tmp += get_num(a[i]);
    }
    return tmp;
}
string word[150];
char aim[330];
int len;
string ans[150];
void dfs(int id,int num){
    if(id == len){
        for(int i = 0;i < num;i++){
            if(i==0) cout<<ans[i];
            else cout<<" "<<ans[i];
        }
        cout<<"."<<endl;
        return ;
    }
    string tmp = "";
    int lenv,mtmp,vnum;
    for(int i = id;i < len;i++){
        tmp += aim[i];
        mtmp = ma[tmp];
        if(mtmp){
            lenv = ve[mtmp].size();
            for(int j = 0;j < lenv;j++){
                vnum = ve[mtmp][j];
                ans[num] = word[vnum];
                dfs(i+1,num+1);
                ans[num] = "";
            }
        }
    }
    return ;
}
int main()
{
    int n,tmp,vis[150];
    string changed[150];
    //freopen("D.in.cpp","r",stdin);
    while(~scanf("%d",&n)){
        if(!n) break;
        ma.clear();
        for(int i = 1;i <= n;i++){
            cin>>word[i];
            changed[i] = change(word[i]);
            ma[changed[i]] = i;
            ve[i].clear();
        }
        memset(vis,0,sizeof(vis));
        for(int i = 1;i <= n;i++){
            if(vis[i]) continue;
            tmp = ma[changed[i]];
            for(int j = i;j <= n;j++){
                if(changed[i] == changed[j]){
                    vis[j] = 1;
                    ve[tmp].push_back(j);
                }
            }
        }
        scanf("%s",aim);
        len = strlen(aim);
        dfs(0,0);
        printf("--\n");
    }
    return 0;
}
时间: 2024-10-07 22:53:11

UVALive 2403 77377解题报告(深搜)的相关文章

UVALive 2053 Puzzlestan(深搜+技巧)

这个题目的深搜形式,我也找出来了,dfs(i,j)表示第i个人选到了第j个物品,但是我却无限RE了,原因是我的viod型深搜太过暴力,我当时定义了一个计数器,来记录并限制递归的层数,发现它已经递归到了1500层,加上限制后,WA了……后来学习了网上的方法,使用bool型的深搜,每一次选择都去跟题目中给的限制去比较,看这次选择有没有冲突,如果没有搜下一个,当搜到false的时候,及时停止,节省了时间和空间. 伪代码: if(dfs(next)==true) return true: else re

最短路问题------分别用深搜和广搜去解题

最少步数 时间限制:3000 ms | 内存限制:65535 KB 难度:4 描述 这有一个迷宫,有0~8行和0~8列: 1,1,1,1,1,1,1,1,1 1,0,0,1,0,0,1,0,1 1,0,0,1,1,0,0,0,1 1,0,1,0,1,1,0,1,1 1,0,0,0,0,1,0,0,1 1,1,0,1,0,1,0,0,1 1,1,0,1,0,1,0,0,1 1,1,0,1,0,0,0,0,1 1,1,1,1,1,1,1,1,1 0表示道路,1表示墙. 现在输入一个道路的坐标作为起点

UVALive 7299 Boggle(深搜的姿势)

一开始确实是我的锅,我把题意理解错了,以为是一个q周围没有q的时候才可以当时qu,其实是只要碰到q,他就是qu,所以我们也可以通过预处理的方式,把字典中的不满足qu连在一起的直接去掉. 后来的各种TIE我就表示不能理解了……我换了好多个姿势,改了各种各样的形式,最后改的快跟学长一模一样了,还是TLE……WTF,真是见了鬼了,最后我发现学长的代码里,字符串的长度没有作为参数传进去,而是在里面直接计算的,我的是把长度计算好了,存起来,直接传参进入递归.结果还真就是因为这个,TLE了,我把这个参数去了

soj 1015 Jill&#39;s Tour Paths 解题报告

题目描述: 1015. Jill's Tour Paths Constraints Time Limit: 1 secs, Memory Limit: 32 MB Description Every year, Jill takes a bicycle tour between two villages. There are different routes she can take between these villages, but she does have an upper limit

poj 1274 The Perfect Stall 解题报告

题目链接:http://poj.org/problem?id=1274 题目意思:有 n 头牛,m个stall,每头牛有它钟爱的一些stall,也就是几头牛有可能会钟爱同一个stall,问牛与 stall 最大匹配数是多少. 二分图匹配,匈牙利算法入门题,留个纪念吧. 书上看到的一些比较有用的知识: 增广:通俗地说,设当前二分图中,已有 x 个匹配边(代码中match[i] 不为0的个数有x个),现在对 i 点(也就是代码中dfs中的参数 x) 指定一个匹配点 j, 由于 j 可能有匹配点设为

哈理工新生赛热身赛解题报告

本次热身赛6道题目,由于没有官方解题报告,自己写了一个山寨版的解题报告,希望对学弟学妹有所帮助 期中两到签到题该校OJ上没有挂出,我在田大神的帮助下a掉了其它四题,解题报告如下所示 线段 Time Limit: 1000 MS Memory Limit: 32768 K Total Submit: 10(6 users) Total Accepted: 7(6 users) Rating:  Special Judge: No Description 坐标轴上有一些点,依次给出.点与点之间要求用

NOIP 2000解题报告

题目简单,思路很快就有,关键是代码实现能力,大概3个多小时完成.第一题:题目大意:将一个10进制数N转换成-B进制数 (负进制转换):B<=20, N(-32768<=N<=32767): 解题过程:首先想到仿照 正进制转换过程,但结果中有负数,就想到把负数处理掉,加个B即可,为了是结果不变,比它高1位的那一位要加1,这样某一位又有可能出现B这个数字,同理减去一个B,高位减去1:重复知道全部是0到B-1的数字:40分钟一次AC 第二题:题目大意:给定一个N位数字,用k个乘号将其划分为k+

[LeetCode]3Sum,解题报告

题目 Given an array S of n integers, are there elements a, b, c in S such that a + b + c = 0? Find all unique triplets in the array which gives the sum of zero. Note: Elements in a triplet (a,b,c) must be in non-descending order. (ie, a ≤ b ≤ c) The so

深搜(DFS),回溯,Fire Net

题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=2 解题报告: 这里的深搜有一点不同,就是,在深搜每一个点时,都要深搜每一个点,就是一个完全二叉树. 借鉴:http://blog.csdn.net/zxy_snow/article/details/5952668 #include <stdio.h> #include <iostream> #include <stdlib.h> using