这周出了四道贪心算法的题,直接让我松一口气。(终于不需要用到我知识盲区里的东西了,除了第四道)
三国游戏
题干很长啊(后面几题都是这样)。总而言之就是,你不能把每一行(每一列)最大的默契值对应的两个武将都抢到, 但是可以抢到次大的(因为电脑把最默契武将的另一半抢走以后又到你选了)。
那么答案就很好想了,给每行(每列)次大的数排个序,然后取最大的那个就是答案了。
什么?你问我机器人会不会赢?
既然我们和机器人都抢不到最大的(可能没看到题目说了小涵先手?),而我们又能拿到次大中的最大,那肯定是我们赢喽。
来看代码:
#include<bits/stdc++.h>
using namespace std;
int a[505][505];//re在空间太小是我没想到的...
int N,ans;
int main()
{
cin>>N;
for(int i=0;i<N;i++)
{
for(int j=i+1;j<N;j++)
{
cin>>a[i][j];
a[j][i]=a[i][j];
}
}//这个图表的表达倒是整体让我想的时间最长的
for(int i=0;i<N;i++)
{
sort(a[i],a[i]+N,greater<int>());//找次大
if(ans<a[i][1]) ans=a[i][1];//次大中最大的
}
cout<<1<<endl;//肯定是小涵赢啊
cout<<ans;
return 0;
}
独木桥
这道题有两问,一问最少多久,一问最大要多久。
最少多久很好想,各回各家呗,都往最近的出口方向跑。那么给每个人需要的时间排个序,最大值就是最少需要的时间。
脑子得转个弯才能想明白最大多久怎么处理
我本来想当然的认为,只要找两个相聚最远的人,让他们相向而行,最后出去的人所花的时间就是最大时长,但模拟了一下发现有问题。细想一下才发现,如果按我说的那样执行,所用的时间就是:两人间,距离最远出口更远的人,往最远出口方向跑出,所需要的时间。既然如此,最大时间自然是每个人都往最远的出口跑,再给每个人排序得到的最大值。
来看代码:
#include<bits/stdc++.h>
using namespace std;
int s[100005],b[100005];//数据又开小了...
//s数组代表较小,b代表较大
int L,N,now;
int main()
{
cin>>L>>N;
int k=0;
for(int i=0;i<N;i++)
{
cin>>now;
if(now<L-now+1)
{
s[k]=now;
b[k]=L-now+1;
}
else
{
s[k]=L-now+1;
b[k]=now;
}
k++;
}
sort(s,s+N,greater<int>());//矮子里面挑高个
sort(b,b+N,greater<int>());//高个里面挑高个
cout<<s[0]<<" "<<b[0];
return 0;
}
排队接水
看题目没什么问题,看题干第一眼就笑喷了。这不跟给我们发的教学视频里面的例题一模一样嘛,输入样例都没改过,只是题目名字换了而已。
一边笑一边提交代码,好家伙直接给我零分。
再瞅一眼题干,好吧,还得输出最优状态下的排队顺序。
没事,稍微加点东西就ac了。
代码:
#include<bits/stdc++.h>
using namespace std;
int N,T[1005],a[1005];//a数组是用来记录位次的
double ans;
int main()
{
cin>>N;
for(int i=1;i<=N;i++)
{
cin>>T[i];
a[i]=T[i];
}
sort(T+1,T+1+N);
for(int i=1;i<=N;i++)
{
for(int j=1;j<=N;j++)
{
if(a[j]==T[i])
{
cout<<j;
a[j]=-1;
break;
}
}
if(i!=N) cout<<" ";
else cout<<endl;
}//完成排队
double tot=0;
for(int i=1;i<=N;++i)
tot+=T[i]*(N-i);//贪心
ans=tot/N;
cout<<setiosflags(ios::fixed)<<setprecision(2)<<ans;
return 0;
}
合并果子
我看这周题单的概述里面说,这个第四题要用到优先队列,然后先去了解了一下,这道题就变成了一道水题。
如果我没学优先队列,这会估计还在用数组疯狂TLE。
思路很明确,每次合并后都让最小的再合并。如果放到代码里,那就是把两个最小值读出来以后删掉,把它们的和再塞入优先队列里。
说是优先“队列”,可本质上是容器啊,一开始还弄混了。
看代码:
#include<bits/stdc++.h>
using namespace std;
int n,x,ans;
priority_queue<int,vector<int>,greater<int>>q;
int main()
{
cin>>n;
for(int i=1;i<=n;i++)
{
cin>>x;
q.push(x);
}
while(q.size()>1)
{
int a=q.top();
q.pop();
int b=q.top();
q.pop();
ans+=a+b;
q.push(a+b);
}
cout<<ans<<endl;
return 0;
}
本周内容就是这些了,学了新知识的同时练了脑子,强度刚好能接受。