zoukankan      html  css  js  c++  java
  • 棋盘染色2

    【题目描述】

    有一个5*N的棋盘,棋盘中的一些格子已经被染成了黑色,你的任务是对最少的格子染色,使得所有的黑色能连成一块。

    【输入描述】

    第一行一个整数N(N <= 100),接下来N行每行一个长度为5的01串,1表示所在格子已经被染成了黑色,0表示所在格子没有被染色。

    【输出描述】

    输出一个整数,表示最少需要染色的格子数。

    【样例输入】

    5
    11100
    11000
    10000
    01111
    11111

    【样例输出】

    1

    70分迭代搜索(原谅我蒟蒻):

    源代码:
    
    #include<cstdio>
    #include<cstring>
    int x[4]={0,0,1,-1},y[4]={1,-1,0,0};
    int n,t1,t2,Num,Total;
    bool f[105][6],Vis[105][6];
    void Check(int X,int Y) //遍历全图,统计染色点数。
    {
        Num++;
        Vis[X][Y]=true;
        for(int a=0;a<4;a++)
        {
            int T1=X+x[a];
            int T2=Y+y[a]; //精髓,有的点只有被染色成连通块才会被统计到。
            if (!Vis[T1][T2]&&T1>=1&&T1<=n&&T2>=1&&T2<=5&&f[T1][T2]) 
              Check(T1,T2);
        }
    }
    bool Can(int t) //判断是否合法。
    {
        Num=0; //经过Check()后全图总共有Num个点被染色。
        memset(Vis,false,sizeof(Vis));
        Check(t1,t2); //从最后搜索,挺方便。
        if (Num==Total+t)
          return true; //Total为初始时染色点数,t为DFS()之后多染的点数。
        return false;
    }
    bool DFS(int X,int Y,int Now,int Sum) //迭代搜索,X、Y为坐标,Now表示当前比初始状态多涂了Now个点,Sum表示目标是涂Sum个点。
    {
        if (Now==Sum) //到达极限。
        {
            if (Can(Sum))
              return true; //判断是否已连通。
            return false;
        }
        for (int a=Y+1;a<=5;a++) //搜索并连接节点的该行的右边。
          if (!f[X][a])
          {
                f[X][a]=true;
                if (DFS(X,a,Now+1,Sum))
                  return true;
                f[X][a]=false;
          }
        for (int a=X+1;a<=n;a++) //同理于上,搜索节点所在行的下方所有区域。
          for (int b=1;b<=5;b++)
            if (!f[a][b])
            {
                f[a][b]=true;
                if (DFS(a,b,Now+1,Sum))
                  return true;
                f[a][b]=false;
            }
        return false; //依旧不成立。
    }
    int main()
    {
        scanf("%d",&n);
        for (int a=1;a<=n;a++)
          for (int b=1;b<=5;b++)
          {
            scanf("%1d",&f[a][b]); //真是太神奇了,"%Xd"表示读入X位数,也可忽略空格。
            if (f[a][b])
            {
                Total++; //黑格总数。
                t1=a; //最后的黑格。
                t2=b;
            }
          }
        for (int a=0;a<=5*n-Total;a++) //迭代。
          if (DFS(1,1,0,a))
          {
            printf("%d",a);
            return 0;
          }
    }
  • 相关阅读:
    HDU Ignatius and the Princess III (母函数)
    HDU 1014 Uniform Generator
    HDU 1013 Digital Roots
    HDU u Calculate e
    HDU 1005 Number Sequence 找规律
    Vijos 送给圣诞夜的极光(bfs)
    HDU Sum Problem (一道神坑的水题)
    Vijos CoVH之再破难关(搜索+hash)
    VIjos 晴天小猪历险记之Number (搜索+链表hash)
    Vijos 有根树的同构问题【字符串---最小表示法】
  • 原文地址:https://www.cnblogs.com/Ackermann/p/5779353.html
Copyright © 2011-2022 走看看