题目链接:

https://cn.vjudge.net/problem/UVA-11134

 /*
问题 输入棋盘的规模和车的数量n(1=<n<=5000),接着输入n辆车的所能在的矩阵的范围,计算并输出使得每辆车横竖都不能相互攻击
的摆放方法,能则输出每辆车的坐标,不能则输出"IMPOSSIBLE"。
解题思路 想想怎么将问题分解成几个小问题,不同行不同列的话,将其分成两个一维问题,采用DFS向下搜索,搜的时候注意每个车的
行区间和列区间,找到一种则直接返回,输出对应每辆车的行和列即可。但是超时!!!
使用贪心法,先将所有区间按照右端点的大小进行排序,然后枚举每一个区间,找到一个数k,满足在此区间内,直到所有区间都找到
一个数输出结果或者其中有一个车在其区间内找不到合适的位置则输出IMPOSSIBLE
*/
#include<cstdio>
#include<cstring>
const int N = ; int xl[N],xr[N],yl[N],yr[N];
int n;
int row[N],col[N]; int solve(int ans[],int l[],int r[]); int main()
{
int i;
while(scanf("%d",&n), n != ){
for(i=;i<n;i++){
scanf("%d%d%d%d",&xl[i],&yl[i],&xr[i],&yr[i]);
} if(solve(row,xl,xr) && solve(col,yl,yr)){
for(i=;i<n;i++){
printf("%d %d\n",row[i],col[i]);
}
}
else
printf("IMPOSSIBLE\n");
}
return ;
} int solve(int ans[],int l[],int r[])
{
int cur,minr;//minr为包含k的区间最小右界(刚开始时初始化为最大,便于寻找最小),cur为放k的最优区间(号)
memset(ans,-,sizeof(int)*n);
//memset(ans,-1,sizeof(ans));错误用法,详见分析
int k,i;
for(k=;k<=n;k++){
cur = -,minr = N;//初始化刚开始时初始化为最大,便于寻找最小
for(i=;i<n;i++){//枚举每个区间
if(ans[i] < && l[i] <= k && r[i] < minr){
//该区间没有被用过且k大于等于该区间的左边界且最小右边界也在该区间内
cur = i;//更新 预备将k存放的区间号
minr = r[i];//缩小右边界,也是贪心法的体现,总是放在可行区间的最右侧
}
}
//没有区间能够放置k或者k不满足在最优区间内
if(cur < || k > minr) return ;
//将k放置在cur区间内
ans[cur]=k;
}
return ;
} /*DFS搜索,超时!!!
#include<cstdio>
#include<cstring>
struct REC{
int xr,yr,xl,yl;
}rec[5050]; int row[5050],col[5050],n,flag1,flag2;
int bkrow[5050],bkcol[5050]; void dfsrow(int step);
void dfscol(int step);
int main()
{
int i; while(scanf("%d",&n), n != EOF){
for(i=1;i<=n;i++){
scanf("%d%d%d%d",&rec[i].xl,&rec[i].yl,&rec[i].xr,&rec[i].yr);
} memset(bkrow,0,sizeof(bkrow));
memset(bkcol,0,sizeof(bkcol));
flag1=flag2=0;
dfsrow(1);
dfscol(1); if(flag1 && flag2){
for(i=1;i<=n;i++){
printf("%d %d\n",row[i],col[i]);
}
}
else
printf("IMPOSSIBLE\n"); }
return 0;
} void dfsrow(int step){
if(step == n+1){
flag1=1;
return;
} int j;
for(j=rec[step].xl;j<=rec[step].xr;j++){
if(bkrow[j] == 0){
bkrow[j]=1;
row[step]=j;
dfsrow(step+1); if(flag1)
return;
bkrow[j]=0;
}
}
} void dfscol(int step){
if(step == n+1){
flag2=1;
return;
} int j;
for(j=rec[step].yl;j<=rec[step].yr;j++){
if(bkcol[j] == 0){
bkcol[j]=1;
col[step]=j;
dfscol(step+1); if(flag2)
return;
bkcol[j]=0;
}
}
}*/

  解决这道题的过程还是一波三折的,搜索超时,贪心苦思冥想,最后还栽在了初始化函数memset上,可以看到平时大家使用初始化函数初始化数组时都这样写

1.memset(ans,-1,sizeof(int)*n);

2.memset(ans,-1,sizeof(ans));

意即将ans数组中的内存单元全部初始化为-1,其实只有第一种写法是正确的,这里错误的原因是VC函数传参过程中的指针降级,导致sizeof(a),返回的是一个something*指针类型大小的的字节数,如果是32位,就是4字节。(详见百度百科https://baike.baidu.com/item/memset/4747579?fr=aladdin#reference-[1]-982208-wrap

而第二种用法可以出现在初始化结构体中。

UVA 11134 Fabled Rooks(贪心的妙用+memset误用警示)的更多相关文章

  1. UVA - 11134 Fabled Rooks[贪心 问题分解]

    UVA - 11134 Fabled Rooks We would like to place n rooks, 1 ≤ n ≤ 5000, on a n × n board subject to t ...

  2. UVA 11134 Fabled Rooks 贪心

    题目链接:UVA - 11134 题意描述:在一个n*n(1<=n<=5000)的棋盘上放置n个车,每个车都只能在给定的一个矩形里放置,使其n个车两两不在同一行和同一列,判断并给出解决方案 ...

  3. UVA 11134 - Fabled Rooks(贪心+优先队列)

    We would like to place  n  rooks, 1 ≤  n  ≤ 5000, on a  n×n  board subject to the following restrict ...

  4. uva 11134 - Fabled Rooks(问题转换+优先队列)

    题目链接:uva 11134 - Fabled Rooks 题目大意:给出n,表示要在n*n的矩阵上放置n个车,并且保证第i辆车在第i个区间上,每个区间给出左上角和右小角的坐标.另要求任意两个车之间不 ...

  5. uva 11134 fabled rooks (贪心)——yhx

    We would like to place n rooks, 1 n 5000, on a n nboard subject to the following restrictions• The i ...

  6. UVa 11134 - Fabled Rooks 优先队列,贪心 难度: 0

    题目 https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&a ...

  7. UVa 11134 Fabled Rooks(贪心)

    题目链接  题意  在n*n的棋盘上的n个指定区间上各放1个'车’ , 使他们相互不攻击(不在同行或同列),输出一种可能的方法. 分析 每行每列都必须放车,把行列分开看,若行和列同时有解,则问题有解. ...

  8. UVa 11134 Fabled Rooks (贪心+问题分解)

    题意:在一个n*n的棋盘上放n个车,让它们不互相攻击,并且第i辆车在给定的小矩形内. 析:说实话,一看这个题真是没思路,后来看了分析,原来这个列和行是没有任何关系的,我们可以分开看, 把它变成两个一维 ...

  9. UVA - 11134 Fabled Rooks问题分解,贪心

    题目:点击打开题目链接 思路:为了满足所有的车不能相互攻击,就要保证所有的车不同行不同列,于是可以发现,行与列是无关的,因此题目可以拆解为两个一维问题,即在区间[1-n]之间选择n个不同的整数,使得第 ...

随机推荐

  1. Android自适应屏幕的实现方法

    首先我们先了解下手机分辨率 分辨率是指屏幕上有横竖各有多少个像素目前手机分辨率大概情况如下: QVGA 分辨率:320×240 简    介:QVGA即"Quarter VGA". ...

  2. [jquery]如何实现页面单块DIV区域滚动展示

    // 未实现功能的代码 1(自己写的代码) var _cur_top = $(window).scrollTop(); var num = $(".class_section"). ...

  3. VARCHAR的最大长度的问题

    大家知道,在SQL Server 2000中,VARCHAR的最大长度是8000,如果字符串的长度超过8000,保存在VARCHAR中时就会被截断.如果你需要传入的参数恰好很长,比如是一个xml,很多 ...

  4. Python:windows下scikit-learn 安装和更新

    scikit-learn 报错: from sklearn.model_selection import train_test_split ImportError: No module named m ...

  5. 【转】PowerDesigner快捷键

    一般快捷键 快捷键 说明 F4 打开检查模型窗口,检查模型 F5 如果图窗口内的图改变过大小,恢复为原有大小即正常大小 F6 放大图窗口内的图 F7 缩小图窗口内的图 F8 在图窗口内中查看全部图内容 ...

  6. ionic 2.x 3.x input触发调用键盘搜索及事件

    html (1.input  type='search'   2.将input套在一个带action的form中 ) <form action=""> <ion- ...

  7. MariaDB 使用正则匹配查询(7)

    MariaDB数据库管理系统是MySQL的一个分支,主要由开源社区在维护,采用GPL授权许可MariaDB的目的是完全兼容MySQL,包括API和命令行,MySQL由于现在闭源了,而能轻松成为MySQ ...

  8. 深入字节码理解invokeSuper无限循环的原因

    来一段简单的cglib代码 public class SampleClass { public void test(){ System.out.println("hello world&qu ...

  9. [JavaScript] 根据指定宽度截取字符串

    /** * 根据指定宽度截取字符串 * @param desc 原始字符串 * @param width 该显示的宽度 * @param fontsize 字体大小 12px * @returns { ...

  10. 01-Python的基础知识2

    - Python变量 - 变量就是重复使用的一个量,或者一个代号. - 变量的命名规则: - 必须以下划线或者字母开头,后面接任意数量下划线.字母.或数字. - 4man , 5for 是不可以的 - ...