题目链接:

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. 二分图匹配-HK算法

    先把代码贴上,其他南京回来再补了.. #include <cstdio> #include <cstdlib> #include <cstring> #includ ...

  2. IIS日志存入数据库之二:ETW

    在上一篇文章<IIS日志存入数据库之一:ODBC>中,我提到了ODBC方式保存的缺点,即:无法保存响应时间以及接收和响应的字节数. 如果一定要获取响应时间以及接收和响应的字节数的话,就要另 ...

  3. 键'attachdbfilename'的值无效。

    ---恢复内容开始--- ---恢复内容结束---

  4. AJPFX:什么是止盈?什么是止损?

    在您进行外汇交易后,会碰到Take Profit(止盈)和 Stop Loss(止损)这两个词,均是用作控制风险的工具. 止盈(Take Profit):当单子达到预期的获利价格时锁定盈利.当订单在盈 ...

  5. 识别同音字词pypinyin, 分词 jieba

    一.pypinyin 在处理语音输入指令时, 比如 请给圆圆发消息,那么转化为文字识别时, 无法确定转换的是圆圆还是园园或是源源, 为了解决这个问题, 就把指令转换为拼音来处理,这样就可以处理同音字了 ...

  6. Android------TabLayout的使用

    https://www.jianshu.com/p/2b2bb6be83a8 主要放在 -------> Design库中的TabLayout的使用. margin和padding的区别 外边距 ...

  7. Codeforces Round #425 (Div. 2) B. Petya and Exam(字符串模拟 水)

    题目链接:http://codeforces.com/contest/832/problem/B B. Petya and Exam time limit per test 2 seconds mem ...

  8. Oracle日期格式化以及extract函数的使用

    由于业务需要,这两天在学习Oracle,发现Oracle里面的日期它会给你转成一种很不习惯的格式,于是想着怎么样把它弄成年.月.日的格式来显示,查资料.看文档,最终找到解决办法了,其实是用到了to_c ...

  9. VS2013 编辑器

    1. VS -> 本地Git -> Github 1. 右键单击解决方案,选择“将解决方案添加到源代码管理器”,选择Git 2. 切换到团队资源管理器([菜单]视图->团队资源管理器 ...

  10. postgresql-pgbench(转)

    pgbench测试:   pg9.6.2的pgbench报错: [thunisoft@localhost ~]$ pgbench -S -c 8 -t 60 pgbenchdb Segmentatio ...