uva :10123 - No Tipping(dfs + 几何力矩 )
题目大意:给出l, m, n 分别表示 长度为l 的杠杆, 重量为 m, 有n个物体放在上方。问每次从上面挑选一个物品移除,能否使杠杆继续平衡。这个过程中都能够的话。就输出移除顺序(不唯一) 否则就输出 impossible 。一開始,这个杠杆就不平衡的情况也会是有的。
由于杠杆也是有重量的。
解题思路;
1、这题先前我就不明确什么怎么样的情况下,双支撑点的杠杆不平横。后面看了别人的报告才明确。
首先 我这里有两个支撑点 (1, 2) 左边的为1. 然后1支撑点的左力距为wl1.同理还有wr1, wl2, wr2. 有1个支撑点的力距的值能够比没有支撑点的力距大,由于多个支撑点支撑重量。
所以 这里不平横情况 ( wl1 > wr1 || wr2 > wl2).
2、这题还有时间的问题。直接去dfs是会超时的。所以这里就须要优化。
首先放在两个支撑点中间的物体会使得这个杠杆更加的平衡,因此,这种物体能够最后移除。然后将力距分左右从小到大的排序。
由于要使得移除的不论什么一个过程都须要平衡,所以问题能够转换为把一个一个物体放到一開始为空的杠杆上的状态和顺序,最后逆向输出。物体一个一个放的话,当然是力距小比較不easy发生失衡的现象。
然后左边的物体从例力距小的開始放,假设不能放就换放右边的力距小的物体。
假设两边都不能放就说明是impossible。
注意:这题中间dfs须要考虑细致点,比如怎样推断两边都不能放的情况。假设一边都放完的情况,还有这边放一些去另外一边的情况。
还有两支撑点间的物体尽管dfs不须要考虑,可是他们的力距须要加到总的力距上。
他们的增加会使得杠杆更加平衡,能支撑很多其它的物体。
代码:
#include <stdio.h>
#include <string.h>
#include <algorithm>
#include <stdlib.h>
#include <math.h>
using namespace std; const int N = 30;
int l, m, n, ans[N][2], path[3], cnt[3];
int flag;
double wl1, wl2, wr1, wr2; struct OB { int w, l;
} obl[N], obr[N], obm[N]; bool cmp (const OB & x,const OB &y) { if (abs (x.l * x.w) < abs (y.l * y.w))
return true;
return false;
} void solve (int dir, int cur, int bo) { if (cur >= n) { flag = 1;
return;
}
if (dir == 0) { for (int i = path[dir]; i < cnt[dir]; i++) {
// printf ("%.3lf %.3lf\n", wl1 + ( -3 - obl[i].l) * obl[i].w, wr1);
if (wl1 + (-3 - obl[i].l) * obl[i].w > wr1) { if (bo) { flag = -1;
return;
}
path[dir] = i;
solve( 2 - dir, cur, bo + 1);
if (flag)
return;
} else { ans[cur][0] = obl[i].l;
ans[cur][1] = obl[i].w;
wl1 += (-3 - obl[i].l) * obl[i].w;
wl2 += (3 - obl[i].l) * obl[i].w;
path[dir] = i + 1;
cur++;
bo = 0; }
}
if (path[2 - dir] <= cnt[2 - dir])
solve (2 - dir, cur, bo);
} else { for (int i = path[dir]; i < cnt[dir]; i++) { if (wr2 + (obr[i].l - 3) * obr[i].w > wl2) { if (bo) {
flag = -1;
return;
}
path[dir] = i;
solve (2 - dir, cur, bo + 1);
if (flag)
return;
} else { ans[cur][0] = obr[i].l;
ans[cur][1] = obr[i].w;
wr1 += (obr[i].l + 3) * obr[i].w;
wr2 += (obr[i].l - 3) * obr[i].w;
path[dir] = i + 1;
cur++;
bo = 0;
}
}
if (path[2 - dir] <= cnt[2 - dir])
solve (2 - dir, cur, bo);
}
if (flag)
return;
} int main () { int p, w, t = 0;
while (scanf ("%d%d%d", &l, &m, &n), l || m || n) { wl1 = wr2 = (l - 3.0) * (l - 3.0) * m / l / 4.0;
wl2 = wr1 = (l + 3.0) * (l + 3.0) * m / l / 4.0;
// printf ("wl1 = %.3lfwr1 = %.3lf\n", wl1, wr1);
memset (cnt, 0, sizeof (cnt));
for (int i = 0; i < n; i++) { scanf ("%d%d", &p, &w);
p = p * 2;
if (p <= 3 && p >= -3){ obm[cnt[1]].w = w;
obm[cnt[1]].l = p;
cnt[1]++;
} else { if (p > 3) { obr[cnt[2]].w = w;
obr[cnt[2]].l = p;
cnt[2]++;
} else { obl[cnt[0]].w = w;
obl[cnt[0]].l = p;
cnt[0]++;
}
}
}
sort (obl, obl + cnt[0], cmp);
sort (obr, obr + cnt[2], cmp);
memset (path, 0, sizeof (path));
for (int i = 0; i < cnt[1]; i++) { wr1 += (obm[i].l + 3) * obm[i].w;
wl2 += (3 - obm[i].l) * obm[i].w;
}
printf ("Case %d:\n", ++t);
flag = 0;
if (wl1 <= wr1 && wr2 <= wl2) { solve (0, cnt[1], 0);
}
if (flag != 1)
printf ("Impossible\n");
else { for (int i = n - 1; i >= cnt[1]; i--)
printf ("%d %d\n", ans[i][0]/2, ans[i][1]);
if (cnt[1] - 1 >= 0)
for (int i = cnt[1] - 1; i >= 0; i--)
printf ("%d %d\n", obm[i].l/2, obm[i].w);
}
}
return 0;
}
版权声明:本文博客原创文章,博客,未经同意,不得转载。
uva :10123 - No Tipping(dfs + 几何力矩 )的更多相关文章
- UVA 10123 No Tipping (物理+贪心+DFS剪枝)
Problem A - No Tipping As Archimedes famously observed, if you put an object on a lever arm, it will ...
- uva 10123 - No Tipping dp 记忆化搜索
这题的题意是 在双脚天平上有N块东西,依次从上面取走一些,最后使得这个天平保持平衡! 解题: 逆着来依次放入,如果可行那就可以,记得得有木板自身的重量. /********************** ...
- UVA - 11853 Paintball(dfs)
UVA - 11853 思路:dfs,从最上面超过上边界的圆开始搜索,看能不能搜到最下面超过下边界的圆. 代码: #include<bits/stdc++.h> using namespa ...
- UVA.548 Tree(二叉树 DFS)
UVA.548 Tree(二叉树 DFS) 题意分析 给出一棵树的中序遍历和后序遍历,从所有叶子节点中找到一个使得其到根节点的权值最小.若有多个,输出叶子节点本身权值小的那个节点. 先递归建树,然后D ...
- UVa 572 油田(DFS求连通块)
https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem& ...
- uva 12253 - Simple Encryption(dfs)
题目链接:uva 12253 - Simple Encryption 题目大意:给定K1.求一个12位的K2,使得KK21=K2%1012 解题思路:按位枚举,不且借用用高速幂取模推断结果. #inc ...
- UVA - 1103Ancient Messages(dfs)
UVA - 1103Ancient Messages In order to understand early civilizations, archaeologists often study te ...
- UVa 208 消防车(dfs+剪枝)
https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem& ...
- UVA 11646 - Athletics Track || UVA 11817 - Tunnelling the Earth 几何
题目大意: 两题几何水题. 1.UVA 11646 - Athletics Track 如图,体育场的跑道一圈400米,其中弯道是两段半径相同的圆弧,已知矩形的长宽比例为a:b,求长和宽的具体数值. ...
随机推荐
- POJ3436 ACM Computer Factory 【最大流】
ACM Computer Factory Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 5412 Accepted: 1 ...
- [ACM] 九度OJ 1553 时钟
时间限制:1 秒 内存限制:128 兆 特殊判题:否 提交:1733 解决:656 题目描写叙述: 如图,给定随意时刻,求时针和分针的夹角(劣弧所相应的角). 输入: 输入包括多组測试数据.每组測试数 ...
- Swift - 使用UIImagePickerController从相册选择照片并展示
1,UIImagePickerController介绍 (1)选择相册中的图片或者拍照,都是通过UIImagePickerController控制器实例化一个对象,然后通过self.presentVi ...
- Servlet的学习之Cookie
从本篇开始学习Servlet技术中的Cookie专题. 首先来了解什么是“会话”.会话是web技术中的一个术语,可以简单的理解为:用户打开一个浏览器,点击多个超链接,访问服务器多个web资源,然后关闭 ...
- VC++ WIN32 sdk实现按钮自绘详解.
网上找了很多,可只是给出代码,没有详细解释,不便初学者理解.我就抄回冷饭.把这个再拿出来说说. 实例图片: 首先建立一个标准的Win32 Application 工程.选择a simple Wi ...
- Struts2图片文件上传,判断图片格式和图片大小
1. 配置Struts2能够上传的最大文件大小 使用Struts2进行文件上传的时候,Struts2默认文件大小最大为2MB,如果要传大一点的文件,就需要修改struts.xml配置文件,重新设置能够 ...
- Swift - 列表项尾部附件点击响应(感叹号,箭头等)
列表单元格尾部可以添加各种样式的附件,如感叹号,三角箭头等.而且点击内容区域与点击附件的这两个响应事件是不同的,这样可以方便我们实现不同的功能(比如点击内容则查看详情,点击感叹号则编辑) 1 2 3 ...
- javascript (十二)对象二
JavaScript 中的所有事物都是对象:字符串.数字.数组.日期,等等. 在 JavaScript 中,对象是拥有属性和方法的数据. 属性和方法 属性是与对象相关的值. 方法是能够在对象上执行的动 ...
- Xamarin.forms 自定义dropdownview控件
一 基本说明 想用xamarin做个像美团这样的下拉列表进行条件选择的功能,但是但是找了半天好像没有现成的,也没有其他类似的控件可以走走捷径,再则也没有找到popwindow之类的东东,这里只好使用s ...
- POJ 2632 Crashing Robots(较为繁琐的模拟)
题目链接:http://poj.org/problem?id=2632 题目大意:题意简单,N个机器人在一个A*B的网格上运动,告诉你机器人的起始位置和对它的具体操作,输出结果: 1.Robot i ...