POJ3740

一.  原题链接 http://poj.org/problem?id=3740

二.  思路:

1、直接DFS搜,然后记得把cin cout改成 scanf printf。就不会超时。这道题告诉我们分函数写的重要性。

2、跳舞链,多么优雅名字,写了好久的,然后为什么我写完之后,提交后的时间比DFS多呢。是我太弱了吧- -!

三. 代码

DFS 610ms

#include <iostream>
#include <cstdio>
#include <cstring>
#include <queue>
#include <algorithm>
#include <vector>
#include <string>

using namespace std;

int square[30][500], row, col, mark[500];
int cntMark;
int rememberJ[302];
bool OK;

bool checkRow(int i)
{
    for(int j = 0; j < col; j++){
        if(square[i][j] && mark[j])
            return false;
    }

    return true;
}

//return the last index which is marked;
int markRow(int i)
{
    int j;
    for(j = 0; j < col; j++){
        if(square[i][j]){
            cntMark++;
            mark[j] = true;
        }
    }

    return j - 1;
}

void disMark(int i, int j)
{
    for(; j >= 0; j--){
        if(square[i][j]){
            cntMark--;
            mark[j] = false;
        }
    }
}

void dfs(int i, int j)
{
    if(col == cntMark){
        OK = true;
        return;
    }

    if(i == row || OK)
        return ;

   for(; i < row; i++){
        if(checkRow(i)){
            int preMark = markRow(i);
            dfs(i + 1, preMark + 1);
            disMark(i, preMark);
        }
   }
}

int main()
{
   // freopen("in.txt", "r", stdin);
    int i, j;
    while(scanf("%d%d", &row, &col) != EOF){
        for(i = 0; i < row; i++)
            for(j = 0; j < col; j++)
            scanf("%d", &square[i][j]);

        memset(mark, 0, sizeof(mark));
        cntMark = 0;

        OK = false;

        dfs(0, 0);

        if(OK)
            printf("Yes, I found it\n");
        else
            printf("It is impossible\n");
    }

    return 0;
}

跳舞链810ms

#include <iostream>
#include <cstdio>
#include <cstring>
#include <queue>
#include <algorithm>
#include <vector>
#include <string>

using namespace std;

const int m  = 18, n = 305;

struct node
{
    node *l, *r, *u, *d;
    int IdOfCol, IdOfRow;
};

node heap[m * n], *C[n], *head = NULL;

int row, col, top;

node *newNode()
{
    return &heap[top++];
}

void init()
{
    top = 0;
    head = newNode();
    int j;

    for(j = 1; j <= col; j++){
        C[j] = newNode();
    }

    for(j = 1; j <= col; j++){
        C[j]->l = C[j-1];
        C[j]->r = C[j+1];
        C[j]->d = C[j]->u = C[j];
        C[j]->IdOfCol = j;
    }
    head->IdOfCol = 0;
    head->l = C[col];
    head->r = C[1];
    C[1]->l = head;
    C[col]->r = head;
}


void del(node *C)
{
    C->l->r = C->r;
    C->r->l = C->l;
    node *i, *j;
    for(i = C->d; i != C; i = i->d){
        for(j = i->r; j != i; j = j->r){
            j->u->d = j->d;
            j->d->u = j->u;
        }
    }
}

void resume(node *C)
{
    C->l->r = C;
    C->r->l = C;
    node *i, *j;
    for(i = C->d; i != C; i = i->d){
        for(j = i->r; j != i; j = j->r){
            j->u->d = j;
            j->d->u = j;
        }
    }
}

bool dfs()
{
    node *cur = head->r, *i, *j;
    if(cur == head)
        return true;

    for(i = cur->d; i != cur; i = i->d){

        del(cur);
        for(j = i->r; j != i; j = j->r){
            del(C[j->IdOfCol]);
        }

        if(dfs())
            return true;

        resume(cur);
        for(j = i->r; j != i; j = j->r){
            resume(C[j->IdOfCol]);
        }
    }

    return false;
}


int main()
{
    //freopen("in.txt", "r", stdin);
    int i, j, buffer;
    while(scanf("%d%d", &row, &col) != EOF){
		init();
        for(i = 1; i <= row; i++){
                node *p = NULL, *s = NULL;
            for(j = 1; j <= col; j++){
                scanf("%d", &buffer);
                if(1 == buffer){
                    p = newNode();
                    if(!s)
                       p->l = p->r = p;
                    else
                       p->l = s, p->r = s->r,
                       s->r->l = p, s->r = p;

                    s = p;
                    p->d = C[j];
					p->u = C[j]->u;
					C[j]->u->d = p;
					C[j]->u = p;
					p->IdOfCol = j;
					p->IdOfRow = i;
                }
            }
        }

        if(dfs())
            printf("Yes, I found it\n");
        else
            printf("It is impossible\n");
    }

    return 0;
}


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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值