IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 数据结构与算法 -> 8.9专题赛题解(下) -> 正文阅读

[数据结构与算法]8.9专题赛题解(下)

8.9专题赛题解(下)

PS:沉迷于图论学习无法自拔,因此拖更hhh,明日定会奉上图论大作!请各位亲们敬请期待!告辞!

A - 飞行员兄弟

POJ - 2965 / AcWing 116(难度:简单)

题目:

“飞行员兄弟”这个游戏,需要玩家顺利的打开一个拥有16个把手的冰箱。

已知每个把手可以处于以下两种状态之一:打开或关闭。

只有当所有把手都打开时,冰箱才会打开。

把手可以表示为一个4х4的矩阵,您可以改变任何一个位置[i,j]上把手的状态。

但是,这也会使得第i行和第j列上的所有把手的状态也随着改变。

请你求出打开冰箱所需的切换把手的次数最小值是多少。

输入格式

输入一共包含四行,每行包含四个把手的初始状态。

符号“+”表示把手处于闭合状态,而符号“-”表示把手处于打开状态。

至少一个手柄的初始状态是关闭的。

输出格式

第一行输出一个整数N,表示所需的最小切换把手次数。

接下来N行描述切换顺序,每行输入两个整数,代表被切换状态的把手的行号和列号,数字之间用空格隔开。

如果有多种解决方案,您可以提供其中任何一种解决方案。

数据范围

1≤i,j≤4

Sample Input

-+--
----
----
-+--

Sample Output

6
1 1
1 3
1 4
4 1
4 3
4 4

题意:

输入一个4*4的矩阵,矩阵里每一个元素都是“+”或者“-”,“+”表示开关是闭合状态,“-”表示开关是打开状态,目标是让所有的开关全部打开,相当于是把所有的“+”变成“-”。操作开关有额外的属性,如果要操作一个开关,那么这个开关所在的一行和一列都会被同时操作。操作的意思就是,如果这个开关原本是闭合的,那么操作一次以后,开关就会变成打开状态了,反之亦然。注意,如果存在多种打开冰箱的方式,输出字典序最小的方案

思路:(知识点:位运算)

令冰箱打开状态为“0”,关闭状态为“1”。同样一个地方操作两次没有意义,因为同一个地方操作两次就等于没有操作,所以一个地方只会操作一次。可以考虑暴力枚举,因为它总共的操作数是有限的。总共有16个开关,每种开关有按和不按两种状态,那么所有的方案数就是216,也就是说,若把所有方案全部枚举一遍,就只需要216种方案。那如何判断一个方案是否能把所有矩阵全部变为“0”(时间复杂度是O(n))(与216的时间复杂度相乘,总的时间复杂度大概是106)可以用位运算的方法枚举,直接从0枚举到216-1,因为每个数在二进制表示下都有16位,如果这一位为0表示我不按这个开关,如果这一位为1的话,表示我按这个开关。在这种情况下,就可以通过从0循环到216-1来枚举所有方案。例如,现在枚举出了一个方案k,可以先遍历一下k的哪些位是1,j可以用16次运算来做,从0开始枚举到15,然后判断某一位是不是1,可以用位运算来判断某一位是不是1(k>>i&1)(这步运算可以快速的判断出k的第i位是不是1)从而判断出了哪一位开关需要按。(可以把题目种的矩阵每一位都标一下号)下一步操作可以继续用位运算,如果我们想改变某一个数所在行和列的状态,就可以预先求出这一行和列上所有的数组合起来的二进制表示。相当于我们每次改变一个开关的状态的时候,都可以直接查表得出该异或的数的值,然后直接异或一下就行了。

AC代码:

#include<cstring>
#include<iostream>
#include<algorithm>
#include<vector>

using namespace std;

typedef pair<int,int> PII;
const int N = 4, INF = 100;

int change[N][N];

int get(int x, int y)
{
    return x * N + y;
}

int main()
{
    for (int i = 0; i < N; i ++ )
        for (int j = 0; j < N; j ++ )
        {
            for (int k = 0; k < N; k ++ )
            {
            	change[i][j] += (1 << get(i, k)) + (1 << get(k, j));
            }
            change[i][j] -= 1 << get(i, j);
        }

    int state = 0;
    for (int i = 0; i < N; i ++ )
    {
        string line;
        cin >> line;
        
        for (int j = 0; j < N; j ++ )
        {
        	if (line[j] == '+')
        	{
        		state += 1 << get(i, j);
        	}
        }
    }

    vector<PII> path, temp;
    for (int i = 0; i < 1 << 16; i ++ )
    {
        int now = state;
        temp.clear();
        for (int j = 0; j < 16; j ++ )
            if (i >> j & 1)
            {
                int x = j / 4;
				int y = j % 4;
                now ^= change[x][y];
                temp.push_back({x, y});
            }
        if (!now && (path.empty() || path.size() > temp.size()))
        {
        	path = temp;
        }
    }

    cout << path.size() << endl;
    for (auto &p : path)
        cout << p.first + 1 << ' ' << p.second + 1 << endl;

    return 0;
}

  数据结构与算法 最新文章
【力扣106】 从中序与后续遍历序列构造二叉
leetcode 322 零钱兑换
哈希的应用:海量数据处理
动态规划|最短Hamilton路径
华为机试_HJ41 称砝码【中等】【menset】【
【C与数据结构】——寒假提高每日练习Day1
基础算法——堆排序
2023王道数据结构线性表--单链表课后习题部
LeetCode 之 反转链表的一部分
【题解】lintcode必刷50题<有效的括号序列
上一篇文章      下一篇文章      查看所有文章
加:2021-08-27 12:07:09  更:2021-08-27 12:07:14 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/25 22:36:46-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码