素数方阵(信息学奥赛一本通-T1446)

【题目描述】

CE数码公司开发了一种名为自动涂色机(APM)的产品。它能用预定的颜色给一块由不同尺寸且互不覆盖的矩形构成的平板涂色。

为了涂色,APM需要使用一组刷子。每个刷子涂一种不同的颜色C。APM拿起一把有颜色C的刷子,并给所有颜色为C且符合下面限制的矩形涂色:

为了避免颜料渗漏使颜色混合,一个矩形只能在所有紧靠它上方的矩形涂色后,才能涂色。例如图中矩形F必须在C和D涂色后才能涂色。注意,每一个矩形必须立刻涂满,不能只涂一部分。

写一个程序求一个使APM拿起刷子次数最少的涂色方案。注意,如果一把刷子被拿起超过一次,则每一次都必须记入总数中。

【输入】

第一行为矩形的个数N。下面有N行描述了N个矩形。每个矩形有5个整数描述,左上角的y坐标和x坐标,右下角的y坐标和x坐标,以及预定颜色。

颜色号为1到20的整数。

平板的左上角坐标总是(0, 0)。

坐标的范围是0..99。N小于16。

【输出】

拿起刷子的最少次数。

【输入样例】


0 0 2 2 1 
0 2 1 6 2 
2 0 4 2 1 
1 2 4 4 2 
1 4 3 6 1 
4 0 6 4 1 
3 4 6 6 2

【输出样例】

3

【源程序】

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<string>
#include<cstring>
#include<cmath>
#include<ctime>
#include<algorithm>
#include<utility>
#include<stack>
#include<queue>
#include<vector>
#include<set>
#include<map>
#include<bitset>
#define EPS 1e-9
#define PI acos(-1.0)
#define INF 0x3f3f3f3f
#define LL long long
#define Pair pair<int,int>
const int MOD = 1E9+7;
const int N = 1000000+5;
const int dx[] = {-1,1,0,0,-1,-1,1,1};
const int dy[] = {0,0,-1,1,-1,1,-1,1};
using namespace std;

int n,m;
int bit[6];
bool bprime[100000];
int G[500000][15];
bool vis[500000][10];
int judge[20000][10],tot;
int res[100];

int suf[6];
int sumX[6], sumY[6];
int sum[6];

void build(){//建图
    int x=0;
    for(int i=1;i<=5;i++){
        if(!vis[x][bit[i]]){
            G[x][0]++;
            G[x][G[x][0]]=bit[i];
            vis[x][bit[i]]=true;
        }
        x=((x<<4)|bit[i]);
    }

    x=0;
    for(int i=5;i>=1;i--){
        if(!judge[x][bit[i]])
            judge[x][bit[i]]=++tot;
        x=judge[x][bit[i]];
    }
}

void dfs(int x,int y) {
    if(x==6){
        for(int i=1;i<=5;i++){
            for(int j=1;j<=5;j++){
                int pos=((i-1)<<3)|j;
                printf("%d",res[pos]);
            }
            printf("\n");
        }
        printf("\n");
    }
    else {
        int minn;
        if(G[sumX[x]][0]>G[sumY[y]][0])
            minn=sumY[y];
        else
            minn=sumX[x];
        for(int i=1;i<=G[minn][0];i++){
            int pos=res[((x - 1) << 3) | y] = G[minn][i];

            int flag1,flag2;
            if(x+y!=6)
                flag1=true;
            else{
                flag1=judge[suf[x-1]][pos];
                suf[x]=judge[suf[x-1]][pos];
            }
            if(x!=y)
                flag2=true;
            else{
                flag2=vis[sum[x-1]][pos];
                sum[x]=((sum[x-1]<<4)|pos);
            }

            if(!flag1||!flag2||!vis[sumY[y]][pos]||!vis[sumX[x]][pos])//存在性剪枝
                continue;

            sumX[x]=((sumX[x]<<4)|pos);
            sumY[y]=((sumY[y]<<4)|pos);

            if(y<5)
                dfs(x,y+1);
            else
                dfs(x+1,1);

            sumX[x]>>=4;
            sumY[y]>>=4;
        }
    }
}
int main() {
    scanf("%d%d",&n,&m);
    for(int i=3;i<=99999;i+=2){//判素数
        if(!bprime[i]){
            if(i>=10000){//分解数位
                bit[1]=i/10000;
                bit[2]=i/1000%10;
                bit[3]=i/100%10;
                bit[4]=i/10%10;
                bit[5]=i%10;
                if(bit[1]+bit[2]+bit[3]+bit[4]+bit[5]==n)//各数位和等于素数
                    build();//建图
            }
            for(int j=i*3;j<=99999;j+=2*i)
                bprime[j]=true;
        }
    }
    sum[1]=m;
    sumX[1]=m;
    sumY[1]=m;
    res[1]=m;
    dfs(1,2);
    return 0;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
信息学赛一本题解》目录 alex 一、引言 1. 欢迎词 2. 关于《信息学赛一本题解》 3. 题解使用方法说明 二、初级篇 1. 基本数据结构 a. 数组 b. 链表 c. 栈和队列 2. 基本算法 a. 排序算法 b. 查找算法 c. 递归与分治 3. 动态规划入门 a. 线性动态规划 b. 背包问题 c. 最长公共子序列 4. 图论算法初步 a. 图的表示与遍历 b. 最短路径算法 c. 最小生成树算法 三、中级篇 1. 树与图算法 a. 树的遍历与构建 b. 树的深度优先搜索与广度优先搜索 c. 图的深度优先搜索与广度优先搜索 d. 带权图的最短路径算法 2. 数据结构进阶 a. 堆与堆排序 b. 并查集 c. 线段树 3. 动态规划提高 a. 状态压缩动态规划 b. 概率与期望 c. 区间动态规划 4. 数论与计算几何 a. 素数与公约数 b. 快速幂与模拟退火 c. 凸包与最近对问题 四、高级篇 1. 字符串算法 a. 字符串匹配算法 b. 后缀数组 c. AC自动机 2. 图论算法深入 a. 强连分量 b. 拓扑排序与关键路径 c. 二分图匹配 3. 数据结构高级应用 a. 平衡树 b. 字典树 c. 哈希表 4. 数论与计算几何进阶 a. 组合数学 b. 线性规划与网络流 c. 几何算法的应用 五、附录 1. 常用数学公式 2. 常见算法时间复杂度与空间复杂度 3. 常见数据结构操作复杂度分析 六、参考文献 1. 专业技术书籍推荐 2. 网络资源推荐 过这本《信息学赛一本题解》,读者可以系统地学习和掌握信息学竞赛中常见的算法、数据结构以及相关问题的解法。本书旨在提供一份全面而深入的题解和算法思路,帮助读者培养良好的编程思维和解决问题的能力。无论是初级还是中高级选手,都可以从本书中获得有效的学习资源和指导。祝愿读者在信息学赛的道路上取得优异的成绩!
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值