HDU 1112 The Proper Key DFS+模拟

           这题是我做过的好恶心的模拟题之一,WA了两次,要注意很多细节,主要是题意不好懂。这题题意是给你两个字符矩阵,第一个代表钥匙,第二个代表锁。问你,钥匙能否穿过锁,如若不能,输出钥匙插入锁的最大深度。
#include <stdio.h>
#include <string.h>
#include <iostream>
#include <algorithm>
#include <queue>
#define maxn 1000
#define maxm 10000
#define mem(a, b) memset(a, b, sizeof(a))
using namespace std;

char key[110][110], lock[10010][1010];
int r, c, d, w, ans, tmpl, tmpr;
bool vis[1010][10110];

bool jg(int l, int r, int kd, int ld)
{
    int tmp = 0;
    for(int i = l;i <= r;i++)
    {
        if(key[kd][tmp] == '#'&&lock[ld][i] == '#')
            return false;
        tmp++;
    }
    return true;
}

bool jg2(int ll, int rr, int dd)
{
    int ddl = min(dd, d - 1), ddk = min(r - 1, r - 1 - (dd - d + 1));
    while(ddk >= 0&&ddl >= 0)
    {
        if(!jg(ll, rr, ddk, ddl))
            return false;
        ddk--;
        ddl--;
    }
    return true;
}

void dfs(int ll, int rr, int dd)
{
    if(ans == d + r)
        return;
    vis[ll][dd] = 1;
    bool flag = 0;
    int tmp = dd;
    while(!flag)
    {
        int ddl = min(tmp, d - 1), ddk = min(r - 1, r - 1 - (tmp - d + 1));
        flag = 0;
        while(ddk >= 0&&ddl >= 0)
        {
            if(!jg(ll, rr, ddk, ddl))
            {
                for(int j = ll;j >= 0;j--)
                {
                    if(!vis[j][tmp - 1]&&jg2(j, j + c - 1, tmp - 1))
                        dfs(j, j + c - 1, tmp - 1);
                    else
                        break;
                }
                for(int j = ll + 1;j <= (w - c);j++)
                {
                    if(!vis[j][tmp - 1]&&jg2(j, j + c - 1, tmp - 1))
                        dfs(j, j + c - 1, tmp - 1);
                    else
                        break;
                }
                flag = 1;
                break;
            }
            ddk--;
            ddl--;
        }
        if(!flag)
        {
            tmp++;
            for(int j = ll;j >= 0;j--)
            {
                if(!vis[j][tmp - 1]&&jg2(j, j + c - 1, tmp - 1))
                    dfs(j, j + c - 1, tmp - 1);
                else
                    break;
            }
            for(int j = ll + 1;j <= (w - c);j++)
            {
                if(!vis[j][tmp - 1]&&jg2(j, j + c - 1, tmp - 1))
                    dfs(j, j + c - 1, tmp - 1);
                else
                    break;
            }
        }
        if(tmp == d + r)
            break;
    }
    ans = max(ans, tmp);
}

void inits()
{
    ans = 0;
    mem(vis, 0);
    return;
}

int main()
{
    int cas;
    scanf("%d", &cas);
    while(cas--)
    {
        scanf("%d%d%*c", &r, &c);
        for(int i = 0;i < r;i++)
            scanf("%s", key[i]);
        scanf("%d%d%*c", &d, &w);
        for(int i = 0;i < d;i++)
            scanf("%s", lock[i]);
        if(c > w)
        {
            printf("The key falls to depth 0.\n");
            continue;
        }
        inits();
        for(int i = 0;i <= (w - c);i++)
        {
            int rr = i + c - 1;
            int dd = 0;
            bool flag = 0;
            while(!flag)
            {
                int ddl = min(dd, d - 1), ddk = min(r - 1, r - 1 - (dd - d + 1));
                flag = 0;
                while(ddk >= 0&&ddl >= 0)
                {
                    if(!jg(i, rr, ddk, ddl))
                    {
                        for(int j = i;j >= 0;j--)
                        {
                            if(!vis[j][dd - 1]&&jg2(j, j + c - 1, dd - 1))
                                dfs(j, j + c - 1, dd - 1);
                            else
                                break;
                        }
                        for(int j = i + 1;j <= (w - c);j++)
                        {
                            if(!vis[j][dd - 1]&&jg2(j, j + c - 1, dd - 1))
                                dfs(j, j + c - 1, dd - 1);
                            else
                                break;
                        }
                        flag = 1;
                        break;
                    }
                    ddk--;
                    ddl--;
                }
                if(!flag)
                {
                    vis[i][dd] = 1, dd++;
                    for(int j = i;j >= 0;j--)
                    {
                        if(!vis[j][dd - 1]&&jg2(j, j + c - 1, dd - 1))
                            dfs(j, j + c - 1, dd - 1);
                        else
                            break;
                    }
                    for(int j = i + 1;j <= (w - c);j++)
                    {
                        if(!vis[j][dd - 1]&&jg2(j, j + c - 1, dd - 1))
                            dfs(j, j + c - 1, dd - 1);
                        else
                            break;
                    }
                }
                if(dd == d + r)
                    break;
            }
            ans = max(ans, dd);
            if(ans == d + r)
                break;
        }
        if(ans >= d + r)
            printf("The key can fall through.\n");
        else
            printf("The key falls to depth %d.\n", ans);
    }
    return 0;
}

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-12-20 22:18:41

HDU 1112 The Proper Key DFS+模拟的相关文章

HDU 5438 Ponds dfs模拟

2015 ACM/ICPC Asia Regional Changchun Online 题意:n个池塘,删掉度数小于2的池塘,输出池塘数为奇数的连通块的池塘容量之和. 思路:两个dfs模拟就行了 1 #include <iostream> 2 #include <cstdio> 3 #include <fstream> 4 #include <algorithm> 5 #include <cmath> 6 #include <deque&

hdu 1298 T9(字典树+DFS)

题目连接:hdu 1298 T9 题目大意:模拟手机打字的猜想功能,根据概率,每按一个按键,输出可能性最高的串.先给定N个单词,以及频率, 然后是Q次询问,每次询问给定一个按按键的顺序,以1为终止. 解题思路:对单词表建立字典树,每个节点有一个经过的频率,这个频率是根据所有经过该节点的单词频率总和.然后 DFS搜索一遍,将答案保存在ans中. #include <cstdio> #include <cstring> #include <algorithm> using

hdu 5640 King&#39;s Cake(模拟)

Problem Description It is the king's birthday before the military parade . The ministers prepared a rectangle cake of size n×m(1≤n,m≤10000) . The king plans to cut the cake himself. But he has a strange habit of cutting cakes. Each time, he will cut

hdu 4930 Fighting the Landlords (模拟)

Fighting the Landlords Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 262144/262144 K (Java/Others) Total Submission(s): 160    Accepted Submission(s): 52 Problem Description Fighting the Landlords is a card game which has been a heat for ye

HDU 哈密顿绕行世界问题 (dfs)

Problem Description 一个规则的实心十二面体,它的 20个顶点标出世界著名的20个城市,你从一个城市出发经过每个城市刚好一次后回到出发的城市. Input 前20行的第i行有3个数,表示与第i个城市相邻的3个城市.第20行以后每行有1个数m,m<=20,m>=1.m=0退出. Output 输出从第m个城市出发经过每个城市1次又回到m的所有路线,如有多条路线,按字典序输出,每行1条路线.每行首先输出是第几条路线.然后个一个: 后列出经过的城市.参看Sample output

hdu 4891 The Great Pan (模拟)

为什么要开__int64 巨巨在哪~ # include <stdio.h> # include <algorithm> # include <string.h> using namespace std; int main () { __int64 count; int i,len,cot,cot1,j,flag,n; char a[1001][1030]; while(~scanf("%d",&n)) { getchar(); flag=0

HDU 1241 Oil Deposits --- 入门DFS

题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=1241 /* HDU 1241 Oil Deposits --- 入门DFS */ #include <cstdio> int m, n; //n行m列 char mapp[105][105]; /* 将和i,j同处于一个连通块的字符标记出来 */ void dfs(int i, int j){ if (i < 0 || j < 0 || i >= n || j >= m

HDU 4930 Fighting the Landlords(模拟)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4930 解题报告:斗地主,加了一个四张可以带两张不一样的牌,也可以带一对,判断打出一手牌之后,如果对手没有能够大过你的牌就输出Yes,或者如果你把手上的牌一次性打完也输出Yes,否则输出No,代码有280多行,表示光是敲代码就花了一个多小时,手速还是太慢. 1.首先判断手上的牌能不能一次打完 如果一次性打不完: 2.首先判断对方有没有一对王,有就输出No 3.判断对手有没有四张的牌,如果有,再判断自己

hdu 2489 Minimal Ratio Tree(dfs枚举 + 最小生成树)~~~

题目: 链接:点击打开链接 题意: 输入n个点,要求选m个点满足连接m个点的m-1条边权值和sum与点的权值和ans使得sum/ans最小,并输出所选的m个点,如果有多种情况就选第一个点最小的,如果第一个点也相同就选第二个点最小的........ 思路: 求一个图中的一颗子树,使得Sum(edge weight)/Sum(point weight)最小~ 数据量小,暴力枚举~~~~~dfs暴力枚举C(M,N)种情况. 枚举出这M个点之后,Sum(point weight)固定,进行prim或者K