搜索练习

洛谷P1312(Noip2011 D1T3)
  一道大模拟题, d f s dfs dfs时注意剪枝:

  1. 相同颜色的方块可以跳过
  2. 只有右边有方块才 M o v e Move Move,左边没有方块才 M o v e Move Move( i − 1 i-1 i1列时将其右移,和你在 i i i列时左移是等效的)
#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define inc(i,l,r) for (int i = l; i <= r; ++i)
const int N = 10;
template <typename T>
void read(T &x)
{
    x = 0; ll f = 1; char ch = getchar();
    while (!isdigit(ch)) {if(ch == '-') f = -1; ch = getchar();}
    while (isdigit(ch)) x = (x<<3) + (x<<1) + ch - '0', ch = getchar();
    x *= f;
}

int n;
int mp[N][N], mark[N][N], last[N][N][N], ans[N][5];

void Copy(int x) {
    inc(i,1,5) inc(j,1,7) last[x][i][j] = mp[i][j];
}

void Back(int x) {
    inc(i,1,5) inc(j,1,7) mp[i][j] = last[x][i][j];
    ans[x][1] = ans[x][2] = ans[x][3] = -1;
}

void drop() {
    inc(i,1,5) {
        int x = 0;
        inc(j,1,7) {
            if (!mp[i][j]) x++;
            else {
                if (!x) continue;
                mp[i][j-x] = mp[i][j];
                mp[i][j] = 0;
            }
        }
    }
}

bool update() {
    int f = 0;
    inc(i,1,5) {
        inc(j,1,7) {
            if (i >= 2 && i <= 4 && mp[i-1][j] == mp[i][j] && mp[i][j] == mp[i+1][j] && mp[i][j]) {
                mark[i-1][j] = mark[i][j] = mark[i+1][j] = 1;
                f = 1;
            }
            if (j >= 2 && j <= 6 && mp[i][j-1] == mp[i][j] && mp[i][j] == mp[i][j+1] && mp[i][j]) {
                mark[i][j-1] = mark[i][j] = mark[i][j+1] = 1;
                f = 1;
            }
        }
    }
    if (!f) return 0;
    inc(i,1,5) {
        inc(j,1,7) {
            if (mark[i][j]) {
                mark[i][j] = 0;
                mp[i][j] = 0;
            }
        }
    }
    return 1;
}

void Move(int i, int j, int x) {
    int tmp = mp[i][j];
    mp[i][j] = mp[i+x][j];
    mp[i+x][j] = tmp;
    drop();
    while (update()) drop();

}

bool check() {
    inc(i,1,5) if (mp[i][1]) return false;
    return true;
}

void dfs(int x) {
    if (check()) {
        inc(i,1,n) {
            inc(j,1,3) printf("%d ", ans[i][j]);
            puts("");
        }
        exit(0);
    }
    if (x == n + 1) return;
    Copy(x);
    inc(i,1,5) {
        inc(j,1,7) {
            if (mp[i][j]) {
                if (i <= 4 && mp[i][j] != mp[i+1][j]) {
                    Move(i,j,1);
                    ans[x][1] = i - 1, ans[x][2] = j - 1, ans[x][3] = 1;
                    dfs(x + 1);
                    Back(x);
                }
                if (i >= 2 && !mp[i-1][j]) {
                    Move(i,j,-1);
                    ans[x][1] = i - 1, ans[x][2] = j - 1, ans[x][3] = -1;
                    dfs(x + 1);
                    Back(x);
                }
            }
        }
    }
}

int main()
{
    int x;
    read(n);
    inc(i,1,5) {
        inc(j,1,8) {
            read(x);
            if (!x) break;
            mp[i][j] = x;
        }
    }
    memset(ans, -1, sizeof(ans));
    dfs(1);
    puts("-1");
    return 0;
}

hdu 4801
   2013 2013 2013年区域赛的一道题目, 模拟二阶魔方, 每个面为平面旋转,有逆时针和顺时针两种, 六个面, 6 ∗ 2 = 12 6*2=12 62=12种操作,然后,我们考虑相对的两个面, 一共只有 6 6 6种操作,用数组表示这 6 6 6种操作后的结果. 这个题目最多转 7 7 7次,那么一共有 6 7 = 279936 6^7=279936 67=279936种状态, 可以直接 d f s dfs dfs暴搜求出最多能还原的面

#include <iostream>
#include <cstdio>
using namespace std;
int mp[25];
int n, ans, cnt;

//{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23}
int d[7][25] = {
    {0, 1, 8, 14, 4, 3, 7, 13, 17, 9, 10, 2, 6, 12, 16, 15, 5, 11, 18, 19, 20, 21, 22, 23},//前左
    {0, 1, 11, 5, 4, 16, 12, 6, 2, 9, 10, 17, 13, 7, 3, 15, 14, 8, 18, 19, 20, 21, 22, 23},//前右
    {1, 3, 0, 2, 23, 22, 4, 5, 6, 7, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 9, 8},//上右
    {2, 0, 3, 1, 6, 7, 8, 9, 23, 22, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 5, 4},//上左
    {6, 1, 12, 3, 5, 11, 16, 7, 8, 9, 4, 10, 18, 13, 14, 15, 20, 17, 22, 19, 0, 21, 2, 23},//左上
    {20, 1, 22, 3, 10, 4, 0, 7, 8, 9, 11, 5, 2, 13, 14, 15, 6, 17, 12, 19, 16, 21, 18, 23},//左下
};

void dfs(int cur, int *a)
{
    cnt = 0;
    if (a[0] == a[1] && a[0] == a[2] && a[0] == a[3]) cnt++;
    if (a[4] == a[5] && a[4] == a[10] && a[4] == a[11]) cnt++;
    if (a[6] == a[7] && a[6] == a[12] && a[6] == a[13]) cnt++;
    if (a[8] == a[9] && a[8] == a[14] && a[8] == a[15]) cnt++;
    if (a[16] == a[17] && a[16] == a[18] && a[16] == a[19]) cnt++;
    if (a[20] == a[21] && a[20] == a[22] && a[20] == a[23]) cnt++;
    if(cnt > ans)
        ans = cnt;
    if (cur == 0 || ans == 6) return;
    int b[25];
    for (int i = 0; i < 6; ++i) {
        for (int j = 0; j < 24; ++j) {
            b[j] = a[d[i][j]];
        }
        dfs(cur - 1, b);
    }
}

int main()
{
    while (~scanf("%d", &n)) {
        ans = 0;
        for (int i = 0; i < 24; ++i) {
            scanf("%d", &mp[i]);
        }
        dfs(n, mp);
        printf("%d\n", ans);
    }
    return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
智慧校园的建设目标是通过数据整合、全面共享,实现校园内教学、科研、管理、服务流程的数字化、信息化、智能化和多媒体化,以提高资源利用率和管理效率,确保校园安全。 智慧校园的建设思路包括构建统一支撑平台、建立完善管理体系、大数据辅助决策和建设校园智慧环境。通过云架构的数据中心与智慧的学习、办公环境,实现日常教学活动、资源建设情况、学业水平情况的全面统计和分析,为决策提供辅助。此外,智慧校园还涵盖了多媒体教学、智慧录播、电子图书馆、VR教室等多种教学模式,以及校园网络、智慧班牌、校园广播等教务管理功能,旨在提升教学品质和管理水平。 智慧校园的详细方案设计进一步细化了教学、教务、安防和运维等多个方面的应用。例如,在智慧教学领域,通过多媒体教学、智慧录播、电子图书馆等技术,实现教学资源的共享和教学模式的创新。在智慧教务方面,校园网络、考场监控、智慧班牌等系统为校园管理提供了便捷和高效。智慧安防系统包括视频监控、一键报警、阳光厨房等,确保校园安全。智慧运维则通过综合管理平台、设备管理、能效管理和资产管理,实现校园设施的智能化管理。 智慧校园的优势和价值体现在个性化互动的智慧教学、协同高效的校园管理、无处不在的校园学习、全面感知的校园环境和轻松便捷的校园生活等方面。通过智慧校园的建设,可以促进教育资源的均衡化,提高教育质量和管理效率,同时保障校园安全和提升师生的学习体验。 总之,智慧校园解决方案通过整合现代信息技术,如云计算、大数据、物联网和人工智能,为教育行业带来了革命性的变革。它不仅提高了教育的质量和效率,还为师生创造了一个更加安全、便捷和富有智慧的学习与生活环境。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值