7.13号总结

题目:AtCoder - abc204_d 

解析:

本题用到了动态规划的思想,将烤箱总共需要的容量得到sum,将前i个菜一直dp到n个菜在一个烤箱中可以实现的大小,(一个烤箱能实现那么另一个烤箱一定也能实现)最后再通过判断,找出烤箱容量差距最小的组合,其中两个烤箱较大的容量就是烹饪时间;

代码:

#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define pii pair<int, int>

int main()
{
    ios::sync_with_stdio(0), cin.tie(0);
    int n,sum=0;
    int t[120];
    bool dp[120][100005]={0};//dp[i][j]为当有i个菜时,一个烤箱j个容量是否能实现
    cin>>n;
    for(int i=1;i<=n;i++){
        cin>>t[i];
        sum+=t[i];
    }
    dp[1][0]=true;
    for(int i=0;i<=n;i++){//i为前i个菜肴
        for(int j=0;j<=sum;j++){//j为烤箱容量
            if(dp[i][j]){
                dp[i+1][j]=true;
                dp[i+1][j+t[i]]=true;
            }
        }
    }
    int ans=sum;
    for(int i=1;i<=sum;i++){
        if(dp[n][i]){//n个菜肴能实现时
        //cout<<i<<" ";
            ans=min(ans,max(i,sum-i));//取差距最小的两个烤箱组合
        }
    }
    cout<<ans<<endl;
}

题目:C - 2D Plane 2N Points

AtCoder - arc092_a 

解析:

友好对的条件是红的每个坐标都要小于蓝的对应的坐标;因此对红坐标从大到小排序,对蓝坐标从小到大排序,找出适合的蓝坐标,并取其中最小的y坐标进行标记;最后遍历看标记了多少个点

代码:

#include <bits/stdc++.h>
using namespace std;
#define int long long
#define pii pair<int, int>

signed main()
{
    int n;
    cin>>n;
    vector<pii>a,b;
    for(int i=0;i<n;i++){
        int x,y;
        cin>>x>>y;
        a.push_back({x,y});
    }
    for(int i=0;i<n;i++){
        int x,y;
        cin>>x>>y;
        b.push_back({x,y});
    }
    sort(a.begin(),a.end(),greater<pii>());
    sort(b.begin(),b.end());
    int vis[123]={0};
    for(int i=0;i<n;i++){
        int p=-1;
        for(int j=0;j<n;j++){
            if(vis[j]) continue;
            if(a[i].first>=b[j].first||b[j].second<=a[i].second) continue;
            if(p==-1) p=j;
            else{
                if(b[p].second>b[j].second) p=j;
            }
        }
        if(p!=-1){
            vis[p]=1;
        }
    }
    int ans=0;
    for(int i=0;i<n;i++){
        if(vis[i]) ans++;
    }
    cout<<ans<<endl;
    return 0;
}

题目:D - Cake 123

AtCoder - abc123_d 

解析:

本题如果直接枚举是n的三次复杂度,可以先枚举找到A,B的最大的K个数,然后再用这K个数与C继续枚举,同时还学会一个函数resize(n,m)使用有3种情况:

1、参数n < v.size()时,结果是容器v的size减小到n,删除n之后的元素;(这道题截取就用了这个函数;
2、v.size() < 参数n < v.capacity(),结果是容器v的size增加到n,增加的元素值初始化为m,m省略时,增加元素值为缺省值,即默认值;
3、v.capacity() < 参数n,结果是先增大容量capacity至n,然后初始化值,初始化方法与情况2相同,此时v中的size与capacity均发生改变。

代码:

#include <bits/stdc++.h>
using namespace std;
#define int long long
#define pii pair<int, int>
vector<int>v,ans,vb;
int a[1003],b[1003],c[1003];
signed  main()
{
    ios::sync_with_stdio(0), cin.tie(0);
    int x,y,z,k;
    cin>>x>>y>>z>>k;
    for(int i=0;i<x;i++){
        cin>>a[i];
    }
    for(int i=0;i<y;i++){
        cin>>b[i];
    }
    for(int i=0;i<z;i++){
        cin>>c[i];
    }
    
    for(int i=0;i<x;i++){
        for(int j=0;j<y;j++){
            v.push_back(a[i]+b[j]);
        }
    }
    sort(v.begin(),v.end(),greater<int>());
    v.resize(min((int) v.size(),k));
    for(int i=0;i<v.size();i++){
       for(int j=0;j<z;j++){
           ans.push_back(v[i]+c[j]);
       }
    }
    sort(ans.begin(),ans.end(),greater<int>());
    for(int i=0;i<k;i++) cout<<ans[i]<<endl;
    return 0;
    
}

题目:栈和排序

栈和排序 (nowcoder.com)

解析:

需要掌握栈的使用,需要注意不要空栈访问,本题需要按它给的入栈顺序输出字典序最大的字符串,所以就提前记录a[i]之后的最大值,如果a[i]大于之后的所有,那么直接将a[i]入栈出栈输出,否则,将它推入栈中(后面有比它更大的)。

代码:

#include<bits/stdc++.h>
using namespace std;
#define int long long

signed main(){
      std::ios::sync_with_stdio(0);
      std::cin.tie(0);
      stack<int> st;
      int a[1000006],ma[1000006]={0};
      int n;
      cin>>n;
      for(int i=0;i<n;i++){
         cin>>a[i];
      }
      for(int i=n-1;i>=0;i--){//找出i到n的最小值,
         ma[i]=max(ma[i+1],a[i]);
      }
      int b[1000006]={0},xb=0;
      for(int i=0;i<n;i++){
         st.push(a[i]);
         while(!st.empty()&&st.top()>ma[i+1]){//只要后面没有比栈顶更大的元素就可以出栈了,因为最后小的值入站之后就不能出战了;
            b[xb]=st.top();
            xb++;
            st.pop();
         }
      }
      while(!st.empty()){
         b[xb]=st.top();
         xb++;
         st.pop();
      }
      for(int i=0;i<n;i++){
         cout<<b[i]<<" ";
      }
   return 0;
}

  • 4
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值