C语言贪心算法解题报告Word文件下载.docx
- 文档编号:17180326
- 上传时间:2022-11-28
- 格式:DOCX
- 页数:27
- 大小:26.63KB
C语言贪心算法解题报告Word文件下载.docx
《C语言贪心算法解题报告Word文件下载.docx》由会员分享,可在线阅读,更多相关《C语言贪心算法解题报告Word文件下载.docx(27页珍藏版)》请在冰豆网上搜索。
=a[n])
tea=a[0];
k=tea*2*n+tea*n;
if(tea*n+(tea*2)*n>
w)
printf("
%d\n"
w);
else
if((tea*n+(tea*2)*n)-k==0)
%.0f\n"
(tea*n+(tea*2)*n));
%.1f\n"
tea=a[n];
k=tea*n+tea/2*n;
if(tea*n+(tea/2)*n>
if((tea*n+(tea/2)*n)-k==0)
(tea*n+(tea/2)*n));
}
intmain()
Tea();
return0;
B题:
田忌赛马,输入第一行为马匹数量,后面输入依次是田忌马战斗力与齐王马战斗力(战斗力高的马一定能赢战斗力低的马),赛马赌资赢一场200,输一场-200,平局不加不减,输出田忌最后的赢或输的钱。
思路方法:
此题用贪心算法,能赢一场是一场的思路,先将田忌与齐王马按战斗力从高到低排序,比较最强的马,如果不能战胜齐王最强马,用田忌最弱的马去赌,然后继续比较;
如果可以战胜,则战胜齐王最强马,然后次强马向后比较;
如果是平手,则看最弱的马,如果最弱的马可以战胜齐王最弱的马,则用最弱马与齐王最弱马比较,若不行,则以最弱的马和齐王此时最强的马比较。
intcmp(inta,intb)
returna>
b;
voidFrighting()
intn,t[1010],q[1010],st,sq,win,endt,endq,i;
%d"
&
n)!
=EOF)
if(n==0)
break;
n;
t[i]);
q[i]);
win=0;
st=sq=0;
endt=endq=n-1;
sort(t,t+n,cmp);
sort(q,q+n,cmp);
while(st<
=endt)
if(t[st]>
q[sq])
st++;
sq++;
win++;
elseif(t[st]<
endt--;
win--;
if(t[endt]>
q[endq])
endq--;
elseif(t[st]==t[endt])
win*200);
Frighting();
C题:
一场比赛,首先输入参加的人数N,然后是一等奖,二等奖,三等奖最少与最多的人数,如果人数多出三奖项相加的最小值,则尽可能的让人获得更高的奖项,输出得各奖的人数;
很简单的一道题,开个变量M存一等奖最少人,二等奖最少人,三等奖最少人之和然后让总人数与其相减,最后将剩下人数分配知道N–M等于零时分配完。
#include<
stdio.h>
stdlib.h>
voidC()
intn,FMa,FMi,SMa,SMi,TMa,TMi,a,b,c;
n)!
%d%d%d%d%d%d"
FMi,&
FMa,&
SMi,&
SMa,&
TMi,&
TMa);
n=n-FMi-SMi-TMi;
//我分配剩下人数的核心算法
a=FMa-FMi;
b=SMa-SMi;
c=TMa-TMi;
while(n!
=0)
if(a!
=0)
n--;
a--;
FMi++;
elseif(b!
b--;
SMi++;
elseif(c!
c--;
TMi++;
%d%d%d\n"
FMi,SMi,TMi);
C();
D题:
首先输入一个数N表示接下来一共有多少个数,然后输入N个数,最后输入一个数K,表示剔除数的个数。
分析算法:
我们学习了C++库函数,定义一个变量M,用M=unique(a,a+n)-a;
找到去重后数的个数。
最后用N–M与K比较,因为要数种类尽可能的多,所以当N–M大于K时,不必牺牲数的种类,直接输出K,否则输出M-(K-(N–M))
voidMostKind()
intn,a[1001],i,m,k;
k);
sort(a,a+n);
m=unique(a,a+n)-a;
if(k<
=n-m)
m);
m-(k-(n-m)));
MostKind();
E题:
题意:
要在陆地上安装雷达,使其可以覆盖到海中所有的岛屿;
其中以x轴为陆地。
求出安装的最少雷达数。
输入的的第一行包含两个数n和d,n表示小岛个数,d表示一个雷达的扫描最远距离(注:
雷达的扫描区域是一个以d为半径的圆);
接下来的n行输入小岛的坐标。
解题思路:
对每个小岛来说要被扫描到则x轴上的雷达位置有两个极限值,超过极限值就不能被扫描到了。
因此当有想同的包含区间时就只需一个雷达,每次只需考虑极限较小的就行,因为小的极限会包含大的。
列如:
小岛A的扫描区间为[a1,a2],即在a1到a2这个区间内的雷达都可扫描到小岛A,小岛B的扫描区间为[b1,b2],如果a1<
=b1&
&
b2<
=a2;
那么小岛A的扫描区间包含小岛B,所在小岛B的扫描区间内的雷达都可扫描到小岛A;
贪心策略:
按照b1<
=b2<
=b3…(b相同时按a从大到小)的方式排序排序,从前向后遍历,当遇到没有加入集合的区间时,选取这个区间的右端点b。
math.h>
intfind_a(intn);
structnode
doublebig;
doublesmall;
}a[1010];
//记录小岛可被扫描到的在X轴上的圆心所在区间
intcmp(nodes,nodet)//使其按从小到大的顺序排列
if(s.small==t.small)
returns.big<
t.big;
returns.small<
t.small;
intn,r,i,x,y,t=0,flag,sum=0;
doubleo;
r)!
flag=0;
if(r<
0)
flag=1;
x,&
y);
if(y>
r)//当纵坐标大于雷达扫描半径时则无法达到全部覆盖要求,即此时无需再处理了
if(!
flag)
o=r*r-y*y;
o=sqrt(o);
a[i].big=o+x;
//可以扫描到该点最大圆心横坐标
a[i].small=x-o;
//可以扫描到该点最小圆心横坐标
if(flag)//无法达到覆盖所有岛屿的要求
sum=-1;
sort(a,a+n,cmp);
sum=find_a(n);
t++;
Case%d:
%d\n"
t,sum);
intfind_a(intn)//寻找所需雷达数
intsum=1,j,i;
doubles=a[0].big;
for(i=1;
n;
i++)//遍历所有小岛可被雷达扫描到的区间
if(a[i].small>
s)//当前起始的区间无法扫描到这个小岛
sum++;
s=a[i].big;
if(s>
a[i].big)//这个小岛的可被扫描到的区间更小,因此得以小区间为准
returnsum;
F题:
首先输入两个数N与S表示一共有几周并且每个牛奶存一周需要花费的钱。
接下是N组数,表示当前周制造一箱牛奶的单价与当前周需要的牛奶数。
输出制造所有牛奶的最低成本。
这道题比较考想法,如果想到了,也是非常简单的。
我们可以这样想,先拿第二周的牛奶减第一周的牛奶的价钱与存储所需的钱比较,如果小于S,则不必要多生产,只需生产当月的量,否则就把第二周的牛奶制造了,而第二周的牛奶成本变成了第一周牛奶的成本加上S,最后以新的“成本价”乘上数量算出最低成本价。
structmilk
intmoney;
intnumber;
}Milk[10005];
voidF()
intn,s,i;
doublesum;
s)!
Milk[i].money,&
Milk[i].number);
sum=Milk[0].money*Milk[0].number;
if(Milk[i-1].money+s>
Milk[i].money)
sum+=Milk[i].money*Milk[i].number;
sum+=(Milk[i-1].money+s)*Milk[i].number;
sum);
F();
G题:
有1*1、2*2、3*3、4*4、5*5、6*6的六种等高的物品,现在告诉你各种物品的个数,将其放入6*6的箱子内,问最少要多少个6*6的箱子
输入:
有多组测试数据,输入六个整数,依次是1*1、2*2、3*3、4*4、5*5、6*6的物品数目;
输出所需的6*6箱子的最少数目。
装箱问题,利用贪心的思想,从最大的开始装6×
6,5×
5和4×
4的每个都需要一个箱子5×
5的和11个1×
1的装一起,4×
4的和5个2×
2的装一起3×
3的分4种情况
1.正好装满
2.剩一个,则装5个2×
2的,7个1×
1的
3.剩两个,则装3个2×
2,6个1×
4.剩三个,则装1个2×
2的,5个1×
还要多余的2×
2的,装完后用1×
1的填充
若2×
2的不够,原来用2×
2的用1×
intcnt2[4]={0,5,3,1};
//记录装了3*3的物品后填充2*2的情况
inti,d[7];
while
(1)
intsum=0;
=6;
d[i]);
sum+=d[i];
sum)
intans=0;
ans+=d[6]+d[5]+d[4]+(d[3]+3)/4;
//计算6*6、5*5、4*4、3*3花费的箱子数
intd2=d[4]*5+cnt2[d[3]%4];
//计算4*4和3*3需要多少2*2的填充
if(d2<
d[2])//比较2*2的是不是用完了,
ans+=(d[2]-d2+8)/9;
//计算2*2所需的数目
intd1=ans*36-d[6]*36-d[5]*25-d[4]*16-d[3]*9-d[2]*4;
//计算还需1*1的数目
if(d1<
d[1])//比较1*1的是否用完
ans+=(d[1]-d1+35)/36;
ans);
H题:
由于本题我没有做出来,所以可能写的不是很清晰,谅解。
第一行第一个数表示钱的面额n(每一个数能被比它大的数整除),第二个数表示每周应该给一个人多少钱。
下面n行第一个数为面额,第二个数为这种面额的钱有多少张。
问最多能雇佣这个人多少周。
思路:
对于面额大于等于n的钱有多少张就能雇佣多少周。
对于面额小于n的,要想使解最优,那么当然应该浪费的钱最少,那么我们就该找到大于n且最接近n的组合:
从大往小搜,并依次累加,当加上下一个数大于n的时候,不用这个数,从小往大搜、并依次累加,当加到大于等于n时,这个组合就为最优。
举例:
527
1610
810
410
210
110
16+8=24+4=28>
27不要4,保持原来的24,24+1=25+2=27,此时为最优组合,也就是16812.代码如下:
iostream>
using
namespace
std;
const
int
maxn=100000;
struct
lpf
qian;
num;
}a[30];
cmp(struct
lpf
p,struct
q)
return
p.qian>
q.qian;
main()
n,c;
while(~scanf("
n,&
c))
for(int
i=0;
i<
n;
i++)
scanf("
a[i].qian,&
a[i].num);
sort(a,a+n,cmp);
cnt=0,mid;
if(a[i].qian>
=c)
cnt+=a[i].num;
else
mid=i;
break;
need[30],x,y;
while
(1)
x=c;
memset(need,0,sizeof(need));
i=mid;
if(a[i].num==0||x==0)
continue;
y=x/a[i].qian;
y=min(y,a[i].num);
x-=y*a[i].qian;
need[i]=y;
if(x)
i=n-1;
i>
=mid;
i--)
=x&
(a[i].num-need[i]))
need[i]++;
x=0;
m=maxn;
if(need[i]>
0)
m=min(m,a[i].num/need[i]);
cnt+=m;
a[i].num-=m*need[i];
printf("
cnt);
0;
I题:
生化学家发明了一种很有用途的生物体,叫stripies,(实际上,最早的俄罗斯名叫polosatiki,不过科学家为了申请国际专利时方便不得不起了另一个英文名)。
stripies是透明,无定型的,群居在一些象果子冻那样的有营养的环境里。
经过长时间的观察,科学家门发现当两条stripies碰撞融合在一起时,新的stripies的重量并不等于碰撞前2条stripies的重量。
不久又发现重量为m1,m2的stripies碰撞融合在一起,其重量变为2*sqrt(m1*m2)。
科学家很希望知道有什么办法可以限制一群stripies的总重量的减少。
请你帮忙。
你可以认为3条或更多的stripies从来不会碰撞在一起?
?
(Youmayassumethat3ormorestipiesnevercollidetogether.)
要求总重量减少最少,即两个合并后重量为最大,所以每次取最大的两个数就行;
因此用sort函数按大到小排序后,直接取前两个数就可以了,并且合并得到的数也是最大,所以下一次只需取一个就还可以了,直到最后只剩下一个数就可以了。
intn,i;
doublenum[110],result;
n);
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 语言 贪心 算法 解题 报告