hdu4272 LianLianKan(dfs)

LianLianKan

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 1778    Accepted Submission(s): 558


Problem Description
I like playing game with my friend, although sometimes looks pretty naive. Today I invent a new game called LianLianKan. The game is about playing on a number stack.
Now we have a number stack, and we should link and pop the same element pairs from top to bottom. Each time, you can just link the top element with one same-value element. After pop them from stack, all left elements will fall down. Although the game seems to be interesting, it's really naive indeed. 

To prove I am a wisdom among my friend, I add an additional rule to the game: for each top element, it can just link with the same-value element whose distance is less than 6 with it. 
Before the game, I want to check whether I have a solution to pop all elements in the stack.
 

Input
There are multiple test cases.
The first line is an integer N indicating the number of elements in the stack initially. (1 <= N <= 1000)
The next line contains N integer ai indicating the elements from bottom to top. (0 <= ai <= 2,000,000,000)
 

Output
For each test case, output “1” if I can pop all elements; otherwise output “0”.
 

Sample Input
  
  
2 1 1 3 1 1 1 2 1000000 1
 

Sample Output
  
  
1 0 0
 

Source

题目大意:给一个栈,里面放了一些物体,编号相同的同一类,每次只能从栈顶开始,找附近距离小于6的同种物品同时出栈,求能否将栈清空。

题目分析:比赛的时候一读题,觉得很水,于是开始模拟+贪心,贪心了2次发现贪心策略是错的,然后开始想搜索。搜索并不难写,dfs+回溯即可。写完又是各种不过。。。跪了3个多小时。检查许久还是没发现问题。绝望之际再读了下题,发现题目的距离定义。。。不是很清楚,什么是距离,2个相邻点距离算0还是1?按我们的理解应该算1的,但是就是不过,后来随手改了一下,去掉了一个等号,结果笋尖就过了啊有木有。。。。

详情请见代码:

#include <iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<algorithm>
#include<map>
#include<set>
#include<vector>
#include<queue>
using namespace std;
const int N = 1005;
const int M = 100000005;
const double eps = 1e-6;
const double PI = acos(-1.0);

bool flag[N];
int lcm[N];
int llcm[N];
int ok;
int n;

bool judge()
{
    int i;
    for(i = 1;i < n;i += 2)
    {
        if(llcm[i] != llcm[i + 1])
            return false;
    }
    return true;
}

void dfs(int cur)
{
    if(cur == 0)
    {
        ok = 1;
        return;
    }
    if(ok)
        return;
    int i;
    flag[cur] = true;
    int cnt = 0;
    for(i = cur - 1;i >= 1;i --)
    {
        if(flag[i] == false)
            cnt ++;
        if(cnt > 6)//距离。。。。此处跪了3个小时+。。。不能取等!!!
            break;
        if(lcm[i] == lcm[cur])
        {
            if(!flag[i])
            {
                flag[i] = true;
                while(flag[-- cur])
                    ;
                dfs(cur);
                if(ok)
                    return;
                flag[i] = false;
            }
        }
    }
    flag[cur] = false;
}

int main()
{
    int i;
    while(scanf("%d",&n) != EOF)
    {
        for(i = 1;i <= n;i ++)
        {
            scanf("%d",&lcm[i]);
            llcm[i] = lcm[i];
        }
        if(n & 1)
        {
            printf("0\n");
            continue;
        }
        sort(llcm + 1,llcm + n + 1);
        if(!judge())
        {
            printf("0\n");
            continue;
        }
        memset(flag,0,sizeof(flag));
        ok = 0;
        dfs(n);
        if(ok == 1)
            printf("1\n");
        else
            printf("0\n");
    }
    return 0;
}
//0MS	284K
/*
2
2 2
2
2 3
*/
/*
2
1 1
3
1 1 1
2
1000000 1
12
1 1 1 4 4 3 1 3 2 2 1 1
12
3 5 5 4 4 1 1 3 1 2 2 1
24
1 1 1 4 4 3 1 3 2 2 1 1 3 5 5 4 4 1 1 3 1 2 2 1
10
1 4 3 2 5 1 2 3 4 5
100
1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1
10
1 2 3 4 5 1 4 3 2 5
10
1 2 3 4 5 1 4 2 3 5
*/




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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值