题目链接:

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. 12.Scrapy与mongodb交互和设置中间键

    反反爬虫相关机制 Some websites implement certain measures to prevent bots from crawling them, with varying d ...

  2. delphi IsIPAdress 非正则表达式验证IP的方法

    function IsIPAdress(const Value:String):Boolean; var n,x,i: Integer; Posi:Array[..]of Integer; Oktet ...

  3. Elasticsearch 系列1 --- Windows10安装Elasticsearch

    在Windows环境下,ES提供了两种安装方式,一种是通过MSI,特点是简单方便:另一种是绿色安装,解压zip包.本文选择第二种方式. 1. 准备工作 (1) Windows 10 (2) JDK 1 ...

  4. jenkins构建时报错

    配置好项目后,选择立即构建,报错 由于节点管理配置的太低,或者在节点的用法上 选择了不同的方式 解决办法: 1.尽可能的使用这个节点 2.保证配置过程没有错误.

  5. SQLSERVER CXPACKET 等待

    --SQLSERVER CXPACKET 等待 2013-6-11 2 --联机丛书: 3 --当尝试同步查询处理器交换迭代器时出现.如果针对该等待类型的争用成为问题时,可以考虑降低并行度 4 5 6 ...

  6. 【有新题】OCP 12c 062出现大量新考题-14

    choose two You plan to upgrade your Oracle Database 9i to Oracle Database 12c. Which two methods can ...

  7. 修改oracle默认监听端口

    修改oracle默认监听端口 oracle端口修改 主要是修改两个文件和修改oracle参数local_listener 1 查看当前监听状态 [oracle@test ~]$ lsnrctl sta ...

  8. 关于SQL的常用操作(增、删、改、查)

    关于SQL的常见操作主要是增.删.改.查. 1.增,顾名思义就是新增数据(insert into).该语句用于向表中插入新纪录.insert into有两种用法. (1).无需指定要插入数据的列名,只 ...

  9. 机器学习与Tensorflow(1)——机器学习基本概念、tensorflow实现简单线性回归

    一.机器学习基本概念 1.训练集和测试集 训练集(training set/data)/训练样例(training examples): 用来进行训练,也就是产生模型或者算法的数据集 测试集(test ...

  10. windows 系统安装git的方法

    windows 系统安装git的方法 msysgit是Windows版的Git,从https://git-for-windows.github.io下载 安装默认步骤,一步步安装即可 安装完成后,在开 ...