首页 > 代码库 > 【uva 11134】Fabled Rooks(算法效率--问题分解+贪心)
【uva 11134】Fabled Rooks(算法效率--问题分解+贪心)
题意:要求在一个N*N的棋盘上放N个车,使得它们所在的行和列均不同,而且分别处于第 i 个矩形中。
解法:问题分解+贪心。
由于行、列不相关,所以可以先把行和列均不同的问题分解为2个“在区间[1,n]中选择n个不同的整数,使得第 i 个整数在[Li,Ri]内”的问题。
接下来的贪心很重要:先使区间R从小到大排序,再L。这样在每个合法区间段中尽量往左边选数的情况下,就能保证每个区间的右边一段是灵活合法的,而若R1=R2,由于是从左开始填数,这并不影响。反正我是没有找到反例的......而不像我( ′? ??`)↓说到的一样。
其实呐,我的思考过程是介样的......想着先排序L,再R,直接筛掉每个区间右边与下一个开始重复的那段区间。结果先发现L1=L2时,由于也是从左开始填数,那么突然发现长度为1的区间很“危险”,[1,4]、[1,4]和[2,2]就不行了。(? _ ?) 于是,应该赶紧转换一下思路了!就像有时从前往后贪心不行就从后往前贪心一样,改为先排序R,再L,这样子再试一些特殊数据就发现可以了。
╮(╯_╰)╭ 唉,关于代码,我不会用指针,便使代码长不少吧。
1 #include<cstdio> 2 #include<cstdlib> 3 #include<cstring> 4 #include<algorithm> 5 #include<iostream> 6 using namespace std; 7 #define N 5010 8 9 int n;10 int vis[N];11 struct node{int l,r,id,t;}a[N],b[N];12 int sx[N],sy[N];13 14 bool cmp(node x,node y)15 {16 if (x.r!=y.r) return x.r<y.r;17 return x.l<y.l;18 }19 bool solve()20 {21 sort(a+1,a+1+n,cmp),22 memset(vis,0,sizeof(vis));23 for (int i=1;i<=n;i++)24 {25 bool tf=false;26 for (int j=a[i].l;j<=a[i].r;j++)27 if (!vis[j])28 {29 a[i].t=j, vis[j]=1;30 tf=true; break;31 }32 if (!tf) return tf;33 }34 sort(b+1,b+1+n,cmp),35 memset(vis,0,sizeof(vis));36 for (int i=1;i<=n;i++)37 {38 bool tf=false;39 for (int j=b[i].l;j<=b[i].r;j++)40 if (!vis[j])41 {42 b[i].t=j, vis[j]=1;43 tf=true; break;44 }45 if (!tf) return tf;46 }47 return true;48 }49 int main()50 {51 while (1)52 {53 scanf("%d",&n);54 if (!n) break;55 for (int i=1;i<=n;i++)56 {57 scanf("%d%d%d%d",&a[i].l,&b[i].l,&a[i].r,&b[i].r);58 a[i].id=b[i].id=i;59 }60 if (!solve()) {printf("IMPOSSIBLE\n");continue;}61 for (int i=1;i<=n;i++)62 sx[a[i].id]=a[i].t,sy[b[i].id]=b[i].t;63 for (int i=1;i<=n;i++)64 printf("%d %d\n",sx[i],sy[i]);65 }66 return 0;67 }
【uva 11134】Fabled Rooks(算法效率--问题分解+贪心)
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。