搜索与DP:SLIKAR
Problem: SLIKAR
【题目描述】
Josip 是个奇怪的画家,他想画一幅由 N*N 个点组成的图, N 是一个 2 的乘方
数(1, 2, 4, 8, 16 等.)。每个点要么是黑色的,要么是白色的。 Josip 画画有一个习惯。
他用下列递归的方式画画:
1.如果图像只包含一个点,他可以以任意色画(黑或白)。
2.否则,他把图分成四个大小相等的正方形部分:
3.从四个中选出一个,用白色的填充。
4.从剩余的三个中选一个,用黑色的填充。
5.把剩余的二部分重新按相同的三步进行填充。
不久以后,他发现,用他的方法并不能画出所有的画。请你编一个程序帮他设计一
个画图方案,使得用他的方法画出的画与想得到的画之间的差距最少(不同点的个
数最少)。
【输入说明】
第一行为一个整数 N (1 ≤ N ≤ 512),表示 Josip 画的图的尽寸。 N 是 2 的乘方数。
后面有 N 行,每行由 N 个 0 或 1 组成,表示画中的黑白点。
【输出说明】
输出第一行为最少可能的不同点数。
后面 N 行输出 Josip 可以画出的与目标图最接近的图。
注,第二部分的图可能不唯一。
【约定】
有 50%的点, N 最多是 8。
【样例】
input
4
1111
1111
1111
1111
output
6
0011
0011
0111
1101
这题其实暴搜就可以了,这里我建了一棵四叉树,用来处理二维的区间问题
#include <iostream>
#include <cstring>
#include <cstdio>
using namespace std;
int N,map[][],tot[][];
char s[][];
int work[][]={
{},
{,,,,},
{,,,,},
{,,,,},
{,,,,},
{,,,,},
{,,,,},
{,,,,},
{,,,,},
{,,,,},
{,,,,},
{,,,,},
{,,,,},
};
struct node{
int L,R,U,D,K,sum;
}tr[];
int Q(int U,int D,int L,int R)
{
return tot[D][R]-tot[U-][R]-tot[D][L-]+tot[U-][L-];
}
int S(int U,int D,int L,int R)
{
return (D-U+)*(R-L+);
}
void Build(int Node,int U,int D,int L,int R)
{
tr[Node].L=L;tr[Node].R=R;
tr[Node].U=U;tr[Node].D=D;
if(L==R)return;
Build(*(Node-)+,U,(U+D)/,L,(L+R)/);
Build(*(Node-)+,U,(U+D)/,(L+R)/+,R);
Build(*(Node-)+,(U+D)/+,D,L,(L+R)/);
Build(*(Node-)+,(U+D)/+,D,(L+R)/+,R);
} void Solve(int Node)
{
if(tr[Node].L==tr[Node].R){
tr[Node].sum=;
return;
}
int son[];
son[]=*(Node-)+;son[]=*(Node-)+;
son[]=*(Node-)+;son[]=*(Node-)+; Solve(son[]);Solve(son[]);
Solve(son[]);Solve(son[]); int minn=,minp;
int ss=S(tr[Node].U,tr[Node].D,tr[Node].L,tr[Node].R)/;
for(int i=;i<=;i++)
{
int ret;
int a=son[work[i][]],b=son[work[i][]];
int c=son[work[i][]],d=son[work[i][]];
ret=tr[a].sum+tr[b].sum;
ret+=Q(tr[c].U,tr[c].D,tr[c].L,tr[c].R);
ret+=ss-Q(tr[d].U,tr[d].D,tr[d].L,tr[d].R);
if(ret<minn){
minn=ret;
minp=i;
}
}
int a=son[work[minp][]],b=son[work[minp][]];
int c=son[work[minp][]],d=son[work[minp][]];
tr[a].K=tr[b].K=;
tr[c].K=;tr[d].K=;
tr[Node].sum=minn;
return;
} void Paint(int Node)
{
int son[];
son[]=*(Node-)+;son[]=*(Node-)+;
son[]=*(Node-)+;son[]=*(Node-)+; if(tr[Node].K==){
if(tr[Node].L==tr[Node].R)
return;
Paint(son[]);Paint(son[]);
Paint(son[]);Paint(son[]);
}
else{
for(int i=tr[Node].U;i<=tr[Node].D;i++)
for(int j=tr[Node].L;j<=tr[Node].R;j++)
map[i][j]=tr[Node].K;
}
}
int main()
{
freopen("slikar.in","r",stdin);
freopen("slikar.out","w",stdout);
scanf("%d",&N);
for(int i=;i<=N;i++)scanf("%s",s[i]+);
for(int i=;i<=N;i++)
for(int j=;j<=N;j++)
{
map[i][j]=s[i][j]-'';
map[i][j]+=map[i][j-];
} for(int i=;i<=N;i++)
for(int j=;j<=N;j++)
tot[i][j]=tot[i-][j]+map[i][j]; Build(,,N,,N); Solve(); for(int i=;i<=N;i++)
for(int j=;j<=N;j++)
map[i][j]=s[i][j]-''; tr[].K=;
Paint(); printf("%d\n",tr[].sum);
for(int i=;i<=N;i++){
for(int j=;j<=N;j++)
printf("%d",map[i][j]);
printf("\n");
}
return ;
}
搜索与DP:SLIKAR的更多相关文章
- 记忆化搜索(DFS+DP) URAL 1223 Chernobyl’ Eagle on a Roof
题目传送门 /* 记忆化搜索(DFS+DP):dp[x][y] 表示x个蛋,在y楼扔后所需要的实验次数 ans = min (ans, max (dp[x][y-i], dp[x-1][i-1]) + ...
- 记忆化搜索(DFS+DP) URAL 1501 Sense of Beauty
题目传送门 /* 题意:给了两堆牌,每次从首部取出一张牌,按颜色分配到两个新堆,分配过程两新堆的总数差不大于1 记忆化搜索(DFS+DP):我们思考如果我们将连续的两个操作看成一个集体操作,那么这个操 ...
- 搜索+简单dp
前言:即使是简单的递归,在复杂度过高时也可以使用简单的dp. 一般有两种情况,一是利用dp思想求最优子结构进行搜索剪枝,二是利用搜索进行dp数组的填充. 例题一.hdu1978 题目大意:这是一个简单 ...
- UVALive 4864 Bit Counting --记忆化搜索 / 数位DP?
题目链接: 题目链接 题意:如果一个数二进制n有k位1,那么f1[n] = k,如果k有s位二进制1,那么f2[n] = f1[k] = s. 如此往复,直到fx[n] = 1,此时的x就是n的”K ...
- hdu3555 Bomb (记忆化搜索 数位DP)
http://acm.hdu.edu.cn/showproblem.php?pid=3555 Bomb Time Limit: 2000/1000 MS (Java/Others) Memory ...
- HDU 2476 String painter(记忆化搜索, DP)
题目大意: 给你两个串,有一个操作! 操作时可以把某个区间(L,R) 之间的所有字符变成同一个字符.现在给你两个串A,B要求最少的步骤把A串变成B串. 题目分析: 区间DP, 假如我们直接想把A变成B ...
- hdu_3562_B-number(记忆化搜索|数位DP)
题目连接:http://acm.hdu.edu.cn/showproblem.php?pid=3652 题意:给你一个n,为比n小的能整除13并数字中有13的数有多少个 题解:记忆化搜索:记dp[i] ...
- CF1038E Maximum Matching 搜索/区间DP
题目传送门:http://codeforces.com/problemset/problem/1038/E 题意:给出$N$个方块,每个方块有左右两种颜色$a,b$(可以翻转使左右两种颜色交换)和一个 ...
- POJ-1088 滑雪 (记忆化搜索,dp)
滑雪 Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 86318 Accepted: 32289 Description Mich ...
随机推荐
- web前端开发随手笔记 - 持续更新
本文仅为个人常用代码整理,供自己日常查阅 html 浏览器内核 <!--[if IE]><![endif]--> <!--[if IE 6]><![endif ...
- Android Cursor类的概念和用法
http://www.2cto.com/kf/201109/103163.html 关于 Cursor 在你理解和使用 Android Cursor 的时候你必须先知道关于 Cursor 的几件事情: ...
- 转-SecureCRT设置
原帖地址:http://www.2cto.com/os/201410/341569.html 一.基本设置 1.修改设置 为了SecureCRT用起来更方便,需要做一些设置,需要修改的有如下几处: 1 ...
- 搞一个app需要多久?
//转载文章,看后有感 我有些尴尬地拿着水杯,正对面坐着来访的王总,他是在别处打拼的人,这几年据说收获颇丰,见移动互联网如火如荼,自然也想着要进来干一场,尽管王总从事的行当也算跟IT沾边,但毕竟太长时 ...
- jQuery - 获取内容和属性
jQuery 拥有可操作 HTML 元素和属性的强大方法. jQuery DOM 操作 jQuery 中非常重要的部分,就是操作 DOM 的能力. jQuery 提供一系列与 DOM 相关的方法,这使 ...
- Swift中可选类型(Optional)的用法 以及? 和 ! 的区别 (转载博客,知识分享)
本文转载自:代码手工艺人的博客,原文名称:Swift之 ? 和 ! Swift语言使用var定义变量,但和别的语言不同,Swift里不会自动给变量赋初始值,也就是说变量不会有默认值,所以要求使用变量之 ...
- 关于JavaScript的类的继承
其实最一开始学JS的时候就看过继承的实现.当时只是去试着理解从书上看来的代码段而已.今天又重新思考了一下,感觉这是一个思维探索演进的结果. 继承,即复用. 如果抛开继承的固有思想,让b复用a的成员,最 ...
- Template 模式
Template 模式是很简单模式,但是也应用很广的模式.Template 是采用继承的方式实现算法的异构,其关键点就是将通用算法封装在抽象基类中,并将不同的算法细节放到子类中实现.Template ...
- 使用Eclipse搭建C/C++开发环境(转)
使用Eclipse搭建C/C++开发环境 文章出自:http://www.cnblogs.com/liuxianan/archive/2013/01/15/2861196.html 说明:网上有很多 ...
- [LeetCode OJ] Distinct Subsequences
Given a string S and a string T, count the number of distinct subsequences of T in S. A subsequence ...