A.水题 题意开始有些迷
#include<bits/stdc++.h>
using namespace std;
int main()
{
int n,s;
scanf("%d%d",&n,&s);
int last=0,next;
bool flag=false;
for(int i=0;i<n;i++)
{
int a,b;
scanf("%d%d",&a,&b);
next=a*60+b;
if(next-last>=s+1) {
flag=true;
}
if(flag) continue;
last=next+1+s;
}
printf("%d %d\n",last/60,last%60);
return 0;
}
B.优先队列 注意边界条件的考虑
#include<bits/stdc++.h>
using namespace std;
int main()
{
int n,A,B,S1,pos=0;
priority_queue<int>pq;
while(!pq.empty()) pq.pop();
scanf("%d%d%d",&n,&A,&B);
for(int i=0;i<n;i++)
{
int s;
scanf("%d",&s);
if(i==0) S1=s;
else pq.push(s);
pos+=s;
}
int ans=0,m=S1*A/B,k=pos-m,cnt=0;
while(!pq.empty())
{
if(cnt>=k) {
break;
}
int p=pq.top();
pq.pop();
cnt+=p;
ans++;
}
cout<<ans<<endl;
return 0;
}
C.二分查找 思维题
思路:依次枚举左边的第一个楼梯 左边的第一个电梯 右边的第一个楼梯 右边的第一个电梯 使用这四种方式转移 取得最小值
#include<bits/stdc++.h>
using namespace std;
const int maxn=1e5+5;
const int INF=0x3f3f3f3f;
int stairs[maxn],eve[maxn];
int main()
{
int n,m,cl,ce,v;
scanf("%d%d%d%d%d",&n,&m,&cl,&ce,&v);
//二分查找左边的第一个楼梯 左边的第一个电梯 右边的第一个楼梯 右边的第一个电梯
for(int i=0;i<cl;i++)
scanf("%d",&stairs[i]);
for(int i=0;i<ce;i++)
scanf("%d",&eve[i]);
int q;
scanf("%d",&q);
while(q--)
{
int x1,y1,x2,y2,solve=INF;
scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
if(x1==x2) solve=abs(y1-y2);
else {
int t=abs(x1-x2);
int p1=lower_bound(stairs,stairs+cl,y1)-stairs;
int p2=lower_bound(eve,eve+ce,y1)-eve;
if(p1==0) {
if(stairs[p1]==y1) {
solve=min(solve,t+abs(y1-y2));
}
}
else {
if(stairs[p1]==y1) {
solve=min(solve,t+abs(y1-y2));
}
else {
solve=min(solve,y1-stairs[p1-1]+t+abs(y2-stairs[p1-1]));
}
}
if(p1<cl) {
solve=min(solve,stairs[p1]-y1+t+abs(y2-stairs[p1]));
}
if(p2==0) {
if(eve[p2]==y1) {
solve=min(solve,(t%v?t/v+1:t/v)+abs(y1-y2));
}
}
else {
if(eve[p2]==y1) {
solve=min(solve,(t%v?t/v+1:t/v)+abs(y1-y2));
}
else {
solve=min(solve,y1-eve[p2-1]+(t%v?t/v+1:t/v)+abs(y2-eve[p2-1]));
}
}
if(p2<ce) {
solve=min(solve,eve[p2]-y1+(t%v?t/v+1:t/v)+abs(y2-eve[p2]));
}
}
printf("%d\n",solve);
}
return 0;
}
D.贪心 具体思路详见下面这个博客:https://blog.csdn.net/finalcsdn/article/details/80184035,是个挺麻烦的贪心
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int maxn=3e5+5;
struct node{
int num,id;
};
bool cmp(node a,node b)
{
return a.num<b.num;
}
int main()
{
int n,x1,x2;
node c[maxn];
scanf("%d%d%d",&n,&x1,&x2);
for(int i=1;i<=n;i++)
{
scanf("%d",&c[i].num);
c[i].id=i;
}
sort(c+1,c+1+n,cmp); //从小到大排序
//先满足x1 再满足x2
for(int i=1;i<=n;i++)
{
//从i开始向前取k1个数
int k1=x1%c[i].num?x1/c[i].num+1:x1/c[i].num;
if(i+k1>n) continue;
int k2=x2%c[i+k1].num?x2/c[i+k1].num+1:x2/c[i+k1].num;
if(i+k1+k2>n+1) continue;
printf("Yes\n%d %d\n",k1,k2);
for(int j=i;j<i+k1;j++)
printf("%d ",c[j].id);
printf("\n");
for(int j=i+k1;j<i+k1+k2;j++)
printf("%d ",c[j].id);
printf("\n");
return 0;
}
//先满足x2,再满足x1
for(int i=1;i<=n;i++)
{
//从i开始向前取k1个数
int k1=x2%c[i].num?x2/c[i].num+1:x2/c[i].num;
if(i+k1>n) continue;
int k2=x1%c[i+k1].num?x1/c[i+k1].num+1:x1/c[i+k1].num;
if(i+k1+k2>n+1) continue;
printf("Yes\n%d %d\n",k2,k1);
for(int j=i+k1;j<i+k1+k2;j++)
printf("%d%c",c[j].id,j==i+k1+k2?'\n':' ');
printf("\n");
for(int j=i;j<i+k1;j++)
printf("%d ",c[j].id);
printf("\n");
return 0;
}
printf("No\n");
return 0;
}