2020 寒假记录(一)

2020 冬 寒假记录(一)

费解的开关

https://vijos.org/p/1197

当第 \(i\) 行的状态确定了之后,只有第 \(i+1\) 行可以影响它,也就是翻完第一行后,后面每一行的操作也就是确定的了,所以枚举第一行的32种状态即可。

深搜

#include <iostream>
#include <algorithm>
#include <cstdio>
using namespace std;

int dir[4][2] = { {0,-1},{0,1},{-1,0},{1,0} }, ans;
bool maze[7][7];

void infect(int x, int y) {
    maze[x][y] = !maze[x][y];
    for (int i = 0; i < 4; i++) {
        int tox = x + dir[i][0], toy = y + dir[i][1];
        maze[tox][toy] = !maze[tox][toy];
    }
}

void dfs(int k, int x, int y) {
    if (k > 6)return;
    if (x == 6) {
        int i = 1;
        for (; i <= 5; i++) {
            if (!maze[5][i])break;
        }
        if (i == 6) {
            ans = k < ans ? k : ans;
        }
        return;
    }
    if (x == 1) {
        dfs(k, x + y / 5, y % 5 + 1);
        infect(x, y);
        dfs(k + 1, x + y / 5, y % 5 + 1);
        infect(x, y);
    }
    else {
        if (!maze[x - 1][y]) {
            infect(x, y);
            dfs(k + 1, x + y / 5, y % 5 + 1);
            infect(x, y);
        }
        else
            dfs(k, x + y / 5, y % 5 + 1);
    }
}
int main() {
    int T;
    cin >> T;
    getchar();
    while (T--) {
        ans = 1 << 30;
        for (int i = 1; i <= 5; i++) {
            for (int j = 1; j <= 5; j++) {
                maze[i][j] = (getchar() == '0' ? false : true);
            }
            getchar();
        }
        if (T != 0)
            getchar();
        dfs(0, 1, 1);
        if (ans == (1 << 30)) {
            cout << -1 << endl;
        }
        else {
            cout << ans << endl;
        }
    }

    return 0;
}

位图枚举

32种状态,枚举0~31,5位二进制,1表示翻,0表示不翻

#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>
using namespace std;

int dir[4][2] = { {0,-1},{0,1},{-1,0},{1,0} }, ans;
bool maze[7][7], temp[7][7];

void infect(int x, int y) {
    maze[x][y] = !maze[x][y];
    for (int i = 0; i < 4; i++) {
        int tox = x + dir[i][0], toy = y + dir[i][1];
        maze[tox][toy] = !maze[tox][toy];
    }
}

int main() {
    int T;
    cin >> T;
    getchar();
    while (T--) {
        int res = 7;
        for (int i = 1; i <= 5; i++) {
            for (int j = 1; j <= 5; j++) {
                temp[i][j] = (getchar() == '0' ? false : true);
            }
            getchar();
        }
        if (T != 0) getchar();

        for (int op = 0; op < 32; op++) {
            int steps = 0;
            memcpy(maze, temp, sizeof(temp));
            for (int j = 0; j < 5; j++) {
                if ((op >> j) & 1) {
                    infect(1, j + 1);
                    steps++;
                }
            }
            for (int i = 2; i <= 5; i++) {
                for (int j = 1; j <= 5; j++) {
                    if (!maze[i - 1][j]) {
                        infect(i, j);
                        steps++;
                    }
                }
            }
            int i = 1;
            for (; i <= 5; i++) {
                if (!maze[5][i])break;
            }
            if (i == 6) {
                if (steps < 7) {
                    res = steps < res ? steps : res;
                }
            }
        }
        if (res != 7)cout << res << endl;
        else cout << -1 << endl;
    }

    return 0;
}

翻硬币

https://www.acwing.com/problem/content/description/1210/

总结一下类似开关、翻转问题,有以下特点:

  1. 每个开关只按一次,因为按两次等于没有按,所以按的次数的最大值就是开关的总数目。
  2. 如果存在解,那么按的顺序是无所谓的。
  3. 每个开关的状态会被后面的1个或者多个开关影响。

我们已经知道了按的顺序是无所谓的,就从左往右按,那么前面一个硬币,只有紧跟在后边的一个硬币会影响到它。

#include <iostream>
#include <string>
#include <cstdio>
using namespace std;
string origin, destination;

int main() {
    int cnt = 0;
    cin >> origin >> destination;
    for (int i = 0; i < origin.length(); i++) {
        if (origin[i] != destination[i]) {
            cnt++;
            origin[i] = origin[i] == '*' ? 'o' : '*';
            origin[i + 1] = origin[i + 1] == '*' ? 'o' : '*';
            if (origin.compare(destination) == 0) {
                cout << cnt << endl;
                return 0;
            }
        }
    }

    return 0;
}

带分数

https://www.acwing.com/problem/content/description/1211/

之前没有过这种思维,逐个 dfs ,和枚举思想差不多,但是比枚举方便了很多。

#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
using namespace std;

int N, res = 0;
bool vis[10];
bool check(int k,int a,int c) {
    int b = (N - a) * c;
    bool temp[10];
    memcpy(temp, vis, 10);
    while(b) {
        int index = b % 10;
        if (!index || temp[index]) return false;
        temp[b % 10] = true;
        b /= 10;
        k++;
    }
    if (k == 9)return true;
    return false;
}
void dfs_c(int k,int a,int c) {
    if (a >= N)return;
    if (check(k, a, c)) {
        res++;
        return;
    }
    for (int i = 1; i <= 9; i++) {
        if (!vis[i]) {
            vis[i] = true;
            dfs_c(k + 1,a, c * 10 + i);
            vis[i] = false;
        }
    }
}
void dfs_a(int k, int a) {
    if (a >= N)return;
    if (a > 0)
        dfs_c(k, a, 0);
    for (int i = 1; i <= 9; i++) {
        if (!vis[i]) {
            vis[i] = true;
            dfs_a(k + 1, a * 10 + i);
            vis[i] = false;
        }
    }
}

int main() {
    cin >> N;
    //N = a + b / c;
    //b=(N-a)*c
    dfs_a(0, 0);
    cout << res << endl;
    return 0;
}

The Pilots Brothers‘ refrigerator

http://poj.org/problem?id=2965

DFS

因为“ If there are several solutions, you may give any one of them. ”,搜到第一个就完事了

#include <iostream>
#include <cstdio>
#include <algorithm>
using namespace std;

int path[20][2];
bool flag;
char maze[5][5];

bool check() {
    for (int i = 0; i < 4; i++) {
        for (int j = 0; j < 4; j++) {
            if (maze[i][j] == '+')
                return false;
        }
    }
    return true;
}

void conver(int x, int y) {
    for (int i = 0; i < 4; i++) {
        maze[x][i] = maze[x][i] == '+' ? '-' : '+';
        maze[i][y] = maze[i][y] == '+' ? '-' : '+';
    }
    maze[x][y] = maze[x][y] == '+' ? '-' : '+';
}

void dfs(int cnt, int x, int y) {
    if (flag)return;
    if (check()) {
        cout << cnt << endl;
        for (int i = 0; i < cnt; i++) {
            printf("%d %d\n", path[i][0], path[i][1]);
        }
        flag = true;
        return;
    }

    if (x == 4)return;
    dfs(cnt, x + (y + 1) / 4, (y + 1) % 4);
    path[cnt][0] = x + 1; path[cnt][1] = y + 1;
    conver(x, y);
    dfs(cnt + 1, x + (y + 1) / 4, (y + 1) % 4);
    conver(x, y);
}

int main() {
    for (int i = 0; i < 4; i++) {
        cin >> maze[i];
    }
    dfs(0, 0, 0);
    return 0;
}

位图枚举

#include <iostream>
#include <cstring>
using namespace std;

int maze[5][5], backup[5][5];

void conver(int x, int y) {
    for (int i = 0; i < 4; i++) {
        maze[x][i] ^= 1;
        maze[i][y] ^= 1;
    }
    maze[x][y] ^= 1;
}

bool check() {
    for (int i = 0; i < 4; i++) {
        for (int j = 0; j < 4; j++) {
            if (maze[i][j] == 0)
                return false;
        }
    }
    return true;
}

int main() {
    for (int i = 0; i < 4; i++) {
        for (int j = 0; j < 4; j++) {
            backup[i][j] = (getchar() == '+') ? 0 : 1;
        }
        getchar();
    }

    int res = 0, mmin = 1 << 30;
    int len = 1 << 16;
    //按要求自上而下自左而右
    for (int op = 0; op < len; op++) {
        memcpy(maze, backup, sizeof(int) * 5 * 5);
        int cnt = 0;
        for (int k = 0; k < 16; k++) {
            if ((op >> k) & 1) {
                cnt++;
                conver(k / 4, k % 4);
            }
        }
        if (check() && cnt < mmin) {
            mmin = cnt;
            res = op;
        }
    }
    cout << mmin << endl;
    for (int k = 0; k < 16; k++) {
        if ((res >> k) & 1) {
            cout << (k / 4) + 1 << ' ' << (k % 4) + 1 << endl;;
        }
    }
    return 0;
}

原文地址:https://www.cnblogs.com/czc1999/p/12183287.html

时间: 2024-10-29 19:09:56

2020 寒假记录(一)的相关文章

2020寒假训练记录

目标: 信息学奥赛之数学一本通重学 第一章 数论 第三章 组合数学 第四章 概率 第六章 矩阵 网络流 DP 多项式 生成函数 CFdiv1 30题 整理模板 2020-01-10 添加模板: 辛普森积分 中国剩余定理 矩阵乘法 提交:POJ1006 原文地址:https://www.cnblogs.com/FYH-SSGSS/p/12177888.html

苏州大学2020考研记录(2019.3-2020.2.24)

我记得上一届有个学长也给我分享了一篇考研总结文档 我希望看到这篇文章的你,能有所收获.高效备考.少走点弯路.少踏点坑,冲鸭! 1.3 月初开始准备(大神当然不需要从介个时候开始,但是窝是小菜鸡) 不要盲目考研!不要从众考研!看清形势.看清自己. 或许你的本科学历及知识技能体系已经能让你够到理想的工作.或许了解一下研究生的日常你会被劝退的.或许从一开始就应该冲一下保研.意志不够坚定也请早日放弃(等秋招时 9 月后身边同学已经拿到心仪 offer 了.跟寄几差不多的同学都冲上保研了.而且宝贵的暑假已

窦小凤2020寒假学习心得

2020年1-2月寒假学习心得—窦小凤 一.学习成果 赛事准备上,每天坚持做题,完成代码量6000行(其中还包括了很多知识点学习上的代码). 学习python基础,对python有了基本认识,完成代码1500行(但其中基本都是python中的基础语法) 选择性学习了一些用Java语言讲的数据结构与算法. 前期主要是将Java的基础视频重看了一遍(主要是在学校的时候没认真),然后从最基础入门开始做起,到寒假末来看,自身在Java方面跟在大一上学期还是有较大进步,但仍还有很长的路要走. Python

2020寒假训练计划

今天是2019年的最后一天了,按照计划.应当对Python有了初步了解,Linux基础操作比较熟悉. 是时候分一下方向了,首先看看各个方向该学些什么. Web PHP 在Web通常是以代码审计.PHP各种协议.特性等等情况出现.基础要求是看懂题中的PHP代码,然后要对题目中常见绕过方法有了解.因此,PHP语言上,要学习到面对对象,能了解PHP序列化和反序列化及各种魔法方法.还要多刷题,了解题目的一些常见的考点,针对考点学习. SQL 要学习SQL注入首先要会SQL的基础语法,SQL语法比较简单,

2020寒假在家学习,抗击新型病毒!!!

1月30日 发现了一个非常有意思的博主,她好像也是学习前端的,她的博客不仅有学习体会,还有生活体会,日常感想等等,然后真的写了超级多超级多!!!我突然意识到如果可以像这样将自己的学习.生活记录下来,定时的翻看,也一定会有诸多感悟. 2月1日 今天和爸妈.姐姐弟弟一起上山,山路险阻,光是走一圈就已精疲力竭,但是走路的感觉真的是很爽呀,每天只能呆在家里抗击病毒,心情难免会郁闷.回到家后,从来不午睡的弟弟竟也破天荒睡了一个午觉,真是难得呀.接下来的一个星期我只能靠着5G流量坚强的生活下去QAQ,但我是

寒假记录六

今天完成了实验任务四-RDD编程初级实践,先在网上查了一下资料. Spark大数据处理的核心是RDD,RDD的全称为弹性分布式数据集,对数据的操作主要涉及RDD的创建.转换以及行动等操作,在Spark系列(二)中主要介绍了RDD根据SparkContext的textFile创建RDD的方法,本小节将介绍RDD编程之转换(Transform)和行动(Action)两种操作. RDD是分布式数据集的抽象 RDD是不可变的数据集合,每个RDD都被分成多个分区,这些分区运行在集群中的不同节点上.其中,R

FZU ICPC 2020 寒假训练 4 —— 模拟(一)

P1042 乒乓球 题目背景 国际乒联现在主席沙拉拉自从上任以来就立志于推行一系列改革,以推动乒乓球运动在全球的普及.其中11分制改革引起了很大的争议,有一部分球员因为无法适应新规则只能选择退役.华华就是其中一位,他退役之后走上了乒乓球研究工作,意图弄明白11分制和21分制对选手的不同影响.在开展他的研究之前,他首先需要对他多年比赛的统计数据进行一些分析,所以需要你的帮忙. 题目描述 华华通过以下方式进行分析,首先将比赛每个球的胜负列成一张表,然后分别计算在11分制和21分制下,双方的比赛结果(

寒假记录十二

Sqoop概述 Sqoop是一款开源的工具,主要用于在Hadoop生态系统(Hadoop.Hive等)与传统的数据库(MySQL.Oracle等)间进行数据的传递,可以将一个关系型数据库中的数据导入到Hadoop的HDFS中,也可以将HDFS的数据导入到关系型数据库中. Sqoop导入原理: 在导入开始之前,Sqoop使用JDBC来检查将要导入的表.他检索出表中所有的列以及列的SQL数据类型.这些SQL类型(varchar.integer)被映射到Java数据类型(String.Integer等

寒假记录

左对齐标题 右对齐标题 居中对齐标题 短文本 中等文本 稍微长一点的文本 稍微长一点的文本 短文本 中等文本 一个普通标题 一个普通标题 一个普通标题 短文本 中等文本 稍微长一点的文本 稍微长一点的文本 短文本 中等文本 name 价格 数量 香蕉 $1 5 苹果 $1 6 草莓 $1 7 Tables Are Cool col 1 is left-aligned $1600 col 2 is centered $12 col 3 is right-aligned $1 原文地址:https: