POJ 3802 Cubist Artwork(思维题)

来源:互联网 发布:串口读取电子秤数据 编辑:程序博客网 时间:2024/06/06 03:34
POJ 3802
题目特别长,背景我就不赘述了。讲下大概题目意思。
题目意思是给你一个立体图形的正视图,和侧视图,问你用小正方体达成这样的效果最小个数。结合题目中的图看下,就能知道意思了。
输入数据:
每一行先输入立体的长和宽(n*m),也就是长就是正视图的长,宽就是正视图的长。
然后输入正视图每一列的最大高度,侧视图每一行的最大高度。


这一道题目不考什么算法,主要考思维。
首先确定一个原则,要让最后需要的小正方体最小,那么每个小正方体最好都能对正视图和侧视图做出贡献。
由此可以发现,放在n*m对角线上的正方体对正视图和侧视图都有影响。
就拿第一组样例举例子
5 5
1 2 3 4 5 最优的结果就是把15个小正方体分为1,2,3,4,5这五组,按照顺序放
1 2 3 4 5 在对角线上,这样的解是最优的。


5 5 再来看这一组样例
2 5 4 1 3 咋一看,不能按照上面的策略来做。但其实实质是一样的,尽可能让
4 1 5 3 2 每个正方体对正视图和侧视图有贡献。
这一个样例中,我们看到正视图中有5,侧视图中也有5,那么我们想办法把这两个凑在一起。聪明的你一定可以发现,在(3,2)(第三列,第二行)放上5个正方体就可以达成目的
同样的,我们可以在(1,3)放上4个正方体,在(4,5)放上3个正方体。。。等等
最后有5个恰当的位置都可以放上1,2,3,4,5个正方体,达成效果。
所以最小也只需要15个。

在往深扩展一步,我们可以发现上下两串数字中如果有相同的数字,那么可以找到一个恰当的位置(位置就是以它们所在序号为坐标,参照上面)放正方体。

到这里,答案已经呼之欲出了。聪明的你到这里可以试着写一下。


解题思路:首先找出上面相同的数字,在找有多少对。这个数字只需要加(成对的个数+成单的个数)次,如果找不到成对的数字,就只需要加一次就可以了。

如果你觉得这篇博客帮助了你,请顶一下或关注。

#include<iostream>#include<cstdio>#include<cstring>#include<functional>#include<algorithm>using namespace std;int a[25],b[25];//存储输入数据int cnt1[25],cnt2[25];//用来找成对数字int n,m;int main(){int i,k,ans,num;while(scanf("%d%d",&n,&m),n&&m){k=ans=num=0;memset(cnt1,0,sizeof(cnt1));memset(cnt2,0,sizeof(cnt2));//清空操作for(i=0;i<n;i++){scanf("%d",&a[i]);cnt1[a[i]]++;}for(i=0;i<m;i++){scanf("%d",&b[i]);cnt2[b[i]]++;}//输入数据for(i=1;i<=20;i++)//每个数字最多为20{k=abs(cnt1[i]-cnt2[i]);//成单的个数num=min(cnt1[i],cnt2[i]);//成对的个数ans+=(i*num+i*k);//printf("i=%d k=%d num=%d ans=%d\n",i,k,num,ans);}printf("%d\n",ans);}return 0;}