zoukankan      html  css  js  c++  java
  • POJ 2965 The Pilots Brothers' refrigerator

    题意:有4×4个开关,每改变一个开关的状态,会同时改变同一行和同一列开关的状态,给出初始状态,求最少需要多少步能把所有开关都变成开,并输出方案。

    解法:枚举+剪枝。直接暴力枚举竟然T了……觉得不太科学……2^16*16的复杂度而已……只好加了一个剪枝,记录当前已经枚举过的最佳答案,后来就只枚举到最佳答案,如果超过了最佳答案的步数说明肯定不是最佳方案。

    代码:

    #include<stdio.h>
    #include<iostream>
    #include<algorithm>
    #include<string>
    #include<string.h>
    #include<math.h>
    #include<limits.h>
    #include<time.h>
    #include<stdlib.h>
    #include<map>
    #include<queue>
    #include<set>
    #include<stack>
    #include<vector>
    #define LL long long
    using namespace std;
    int main()
    {
        ios :: sync_with_stdio(false);
        char maze[4][5];
        while(cin >> maze[0])
        {
            for(int i = 1; i < 4; i++)
                cin >> maze[i];
            int maxn = 1 << 16;
            int ans = 1000000, pos = 0;
            for(int i = 0; i < maxn; i++)
            {
                int res = 0;
                int cnt[4][4] = {0};
                int flag = 1;
                for(int j = 0; j < 16; j++)
                {
                    if(i & (1 << j))
                    {
                        res++;
                        if(res > ans)//剪枝
                        {
                            flag = 0;
                            break;
                        }
                        for(int k = 0; k < 4; k++)
                        {
                            cnt[j / 4][k]++;
                            cnt[k][j % 4]++;
                        }
                        cnt[j / 4][j % 4]--;
                    }
                }
                for(int j = 0; j < 4 && flag; j++)
                    for(int k = 0; k < 4 && flag; k++)
                    {
                        int tmp = maze[j][k] == '+' ? 1 : 0;
                        tmp += cnt[j][k];
                        if(tmp & 1) flag = 0;
                    }
                if(flag && (res < ans))
                {
                    ans = res;
                    pos = i;
                }
            }
            if(ans != 1000000)
                cout << ans << endl;
            else
                cout << "0" << endl;
            for(int i = 0; i < 16; i++)
            {
                if(pos & (1 << i))
                {
                    cout << i / 4 + 1 << ' ' << i % 4 + 1 << endl;
                }
            }
        }
        return 0;
    }
    

      

  • 相关阅读:
    常用加密解密类(含3des)
    谷歌API(Ajax)
    flashpaper使用详解
    布置小窝
    CodeSimth数据访问层模板
    CodeSmith业务逻辑层模板
    CodeSimth生成实体类模板
    C# 参考之方法参数关键字:params、ref及out
    ALV 格式常用参数
    BOM输出
  • 原文地址:https://www.cnblogs.com/Apro/p/4859156.html
Copyright © 2011-2022 走看看