题目: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
解析:
友好对的条件是红的每个坐标都要小于蓝的对应的坐标;因此对红坐标从大到小排序,对蓝坐标从小到大排序,找出适合的蓝坐标,并取其中最小的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
解析:
本题如果直接枚举是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;
}
题目:栈和排序
解析:
需要掌握栈的使用,需要注意不要空栈访问,本题需要按它给的入栈顺序输出字典序最大的字符串,所以就提前记录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;
}