洛谷——《贪心》

本文介绍了C++中的多个编程问题解决方案,涉及最长波动子序列、区间最大和、最大差价计算、性价比数组排序、最小二叉树生成、背包问题等,展示了不同的算法和数据结构的使用方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

#include<iostream>
#include<iomanip>
#include<cmath>
#include<string.h>
#include<string>
#include <ctime>
#include<cstdlib>
#include<algorithm>
#include<cstdio>
using namespace std;

//最长波动子序列
// int a[100],b[100];
// void max(int n)
// {
//     int pre = 0;
//     int m = 0;
//     for(int i =0;i<n-1;i++)
//     {
//         int cur = a[i+1]-a[i];
//         if(cur>0&&pre<=0||cur<0&&pre>=0)
//         {
//             b[m++] = a[i];
//             pre = cur;
//         }
//     }
//     b[m] = a[n-1];
//     for(int i =0;i<=m;i++)cout<<b[i]<<' ';
// }
// int main()
// {
//     int n;
//     cin>>n;
//     for(int i =0;i<n;i++)cin>>a[i];
//     max(n);
// }

//区间最大和(有问题)
// int arr[100];
// int main()
// {
//     int n,item,max = 0,ans = 0;
//     int p =0,max_len;
//     cin>>n;
    
//     for(int i =0;i<n;i++)
//     {
//         cin>>item;
//         max +=item;
//         arr[p++]  = item;
//         if(max>ans)
//         {
//             ans = max;
//             max_len = p;
//         }
//         if(max<0)
//         {
//             max = 0;
//             p = 0;
//         }
//     }
//     cout<<ans<<endl;
//     for(int i =0;i<max_len;i++)cout<<arr[i]<<' ';
    
// }

//最大差价
// int arr[100];
// int main()
// {
//     int n;
//     int ans =0;
//     cin>>n;
//     for(int i =0;i<n;i++)cin>>arr[i];
//     for(int i =1;i<n;i++)
//     {
//         if(arr[i]-arr[i-1]>0)ans+=arr[i]-arr[i-1];
//     }
//     cout<<ans<<endl;
// }

// p2240
// 1.性价比数组排序
// 2.按性价比顺序放入
// struct coin
// {
//     int m,v;
// }arr[100];
// bool cmp(coin a,coin b)
// {
//     return a.v*b.m>a.m*b.v;
// }

// int main()
// {
//     int N,T;
//     cin>>N>>T;
//     double ans = 0;
//     int M =0;
//     int S_m =0,S_v = 0;
//     for(int i =0;i<N;i++)
//     {
//         cin>>arr[i].m>>arr[i].v;
//         S_m +=arr[i].m;
//         S_v +=arr[i].v;
//     }
//     //排序
//     sort(arr,arr+N,cmp);
//     int i =0;
//     if(S_m<=T)ans = S_v;
//     else
//     {
//         while(M!=T)
//         {
//             if(M+arr[i].m<=T)
//             {
//                 M +=arr[i].m;
//                 ans +=arr[i].v;
//                 i++;
//             }
//             else
//             {
//                 ans+=(T-M)*1.0*arr[i].v/arr[i].m;
//                 M = T;
//             }
//         }
//     }
    
//     cout<<fixed<<setprecision(2)<<ans;
// }


// p1223
// 1.结构体有编号,时间;
// 2.结构体时间按从小到大排序,时间相同的话按编号从小到大排序
// 3.每一个的等待时间是前面的一个人的等待时间加上前一个花费时间

// struct water
// {
//     int num,t,spend;
// }arr[1010];
// bool cmp(water a,water b)
// {
//     if(a.t!=b.t)return a.t<b.t;
//     else return a.num<b.num;
// }
// int main()
// {
//     int n;
//     long long ans;
//     cin>>n;
//     for(int i =0;i<n;i++)
//     {
//         arr[i].num = i+1;
//         cin>>arr[i].t;
//     }
//     sort(arr,arr+n,cmp);
//     arr[0].spend = 0;
//     for(int i =1;i<n;i++)arr[i].spend = arr[i-1].t+arr[i-1].spend;
//     for(int i =0;i<n;i++)
//     {
//         ans+=arr[i].spend;
//         cout<<arr[i].num<<' ';
//     }
//     cout<<endl;
//     cout<<fixed<<setprecision(2)<<ans*1.0/n;
    

// }

// p1803
// 1.结构体定义开始和结束时间
// 2.结束时间从小到大
// 3.以前一个的结束时间作为开始时间在后面的时间挑选
// struct test
// {
//     int begin,end;
// }arr[1000000];
// bool cmp(test a,test b)
// {
//     return a.end<b.end;
// }
// int main()
// {
//     int n;
//     int ans =0;
//     int sta = -1;
//     cin>>n;
//     for(int i =0;i<n;i++)cin>>arr[i].begin>>arr[i].end;
//     sort(arr,arr+n,cmp);
//     枚举一遍
//     for(int i =0;i<n;i++)
//     {
//         if(arr[i].begin>=sta)
//         {
//             sta = arr[i].end;
//             ans ++;
//         }
//     }
//     cout<<ans;
// }

// p1090
// 1.最小二叉树生成
// 2.找到数组两个最小,相加变成一个,直到最后只剩一个数
// int arr[100000];
// long long ans = 0;
// void merge(int n)
// {
//     if (n == 1) return; // 处理输入为 1 的情况
//     int min_1 = 0x7fffffff, min_2 = 0x7fffffff;
//     int index_1, index_2;
//     for (int i = 0; i < n; i++) {
//         if (arr[i] < min_1) {
//             min_2 = min_1; // 更新第二小的数
//             index_2 = index_1;
//             min_1 = arr[i];
//             index_1 = i;
//         } else if (arr[i] < min_2) {
//             min_2 = arr[i];
//             index_2 = i;
//         }
//     }
//     // 调整
//     arr[index_1] = min_1 + min_2;
//     ans += arr[index_1];
//     arr[index_2] = arr[n - 1]; // 把最后一个数放到 index_2 位置上
//     merge(n - 1);
// }
// int main()
// {
//     int n;
//     cin>>n;
//     for(int i =0;i<n;i++)cin>>arr[i];
//     merge(n);
//     cout<<ans;
// }


//p3817
// 还是有些弄不懂原理
// 1.判断前两项之和数字是否超过,如果超过,后项来减
// long long arr[100000];
// int main()
// {
    
//     long long n,x,ans = 0;
//     cin>>n>>x;
//     for(long long i =1;i<=n;i++)
//     {
//         cin>>arr[i];
//         if(arr[i]+arr[i-1]>x)
//         {
//             ans +=arr[i]+arr[i-1]-x;
//             arr[i] = x-arr[i-1];
//         }
//     }
//     cout<<ans;
// }

// p1106
// 1.肯定是从高位开始减
// 2.如果比后位大,则减去,否则跳过
// 3.如果是最后一位最大,直接减去
// string a,b;
// int main()
// {
//     int n,i;
//     cin>>a>>n;
//     a+='0';
//     int len =a.length();
//     while(n--)
//     {
//         for(i =0;i<len-1;i++)
//         {
//              if(a[i]>a[i+1])
//             {
//                 for(int j =i;j<len;j++)a[j]= a[j+1];
//                 len--;
//                 break;
//             }
//         }
//     }
//     //前0位置
//     int j =0;
//     while(a[j]=='0'&&len-2-j>0)j++;
//     for(i =j;i<len-1;i++)
//     b+= a[i];
//     cout<<b;
// }


// p1478
// 1.结构体定义苹果高度,所耗费力气
// 2.力气排序
// 3.判断高度在不在范围
// struct apple
// {
//     int high,spend;
// }arr[10000];
// bool cmp(apple a,apple b)
// {
//     return a.spend<b.spend;
// }
// int main()
// {
//     int n,s,a,b;
//     int ans = 0,sp =0;
//     cin>>n>>s>>a>>b;
//     for(int i =0;i<n;i++)cin>>arr[i].high>>arr[i].spend;
//     sort(arr,arr+n,cmp);
//     for(int i =0;i<n;i++)
//     {
//         if(arr[i].high<=a+b&&sp+arr[i].spend<=s)
//         {
//             sp +=arr[i].spend;
//             ans++;
//         }
//     }
//     cout<<ans;
// }


// p5019
// 1.哈哈,试试看用递归做一下
// 2.逆向思维:如何挖洞,
// 3.选择最小的位置挖,然后分成左右部分
// int arr[1000000];
// int ans;
// void dig(int left,int right)
// {
//     if(left>right)return;
//     int min =50000;
//     int index =0;
//     //找到最小
//     for(int i =left;i<=right;i++)
//     {
//         if(arr[i]<min)
//         {
//             min =arr[i];
//             index = i;
//         }
//     }
//     //区间减去最小
//     for(int i =left;i<=right;i++)arr[i]-=min;
//     ans+=min;
//     dig(left,index-1);
//     dig(index+1,right);
// }
// int main()
// {
//     int n;
//     cin>>n;
//     for(int i =0;i<n;i++)cin>>arr[i];
//     dig(0,n-1);
//     cout<<ans;
// }


// p1208
// 1.背包问题
// 2.结构体定义单价和产量
// 3.结构体单价排序

// struct milk
// {
//     int price,yield;
// }arr[10000];
// bool cmp(milk a,milk b)
// {
//     return a.price<b.price;
// }
// int ans =0;
// int main()
// {
//     int n,m;
//     cin>>n>>m;
//     int sum =0;
//     for(int i =0;i<m;i++)cin>>arr[i].price>>arr[i].yield;
//     sort(arr,arr+m,cmp);
//     for(int i =0;i<m;i++)
//     {
//         if(sum+arr[i].yield<=n)
//         {
//             ans += arr[i].yield*arr[i].price;
//             sum+=arr[i].yield;
//         }
//         else
//         {
//             ans +=(n-sum)*arr[i].price;
//             break;
//         }
        
//     }
//     cout<<ans;
// }

//p1094
// 1.从大到小排序
// 2.设置左右点移动
// int arr[100000];
// int ans = 0;
// bool cmp(int a,int b)
// {
//     return a>b;
// }
// int main()
// {
//     int w,n;
//     cin>>w>>n;
//     for(int i =0;i<n;i++)cin>>arr[i];
//     sort(arr,arr+n,cmp);
//     int left = 0,right = n-1;
//     while(left<=right)
//     {
//         if(arr[left]+arr[right]<=w)
//         {
//             left++;
//             right--;
//             ans++;
//         }
//         else
//         {
//             left++;
//             ans++;
//         }
//     }
//     cout<<ans;
// }

//p4995
// 1.跨度肯定是越大越好
// 2.从大到小排序
// 3.要left和right
// int arr[1000];
// long long ans =0;
// bool cmp(int a,int b)
// {
//     return a>b;
// }
// int main()
// {
//     int n;
//     cin>>n;
//     for(int i =0;i<n;i++)cin>>arr[i];
//     sort(arr,arr+n,cmp);
//     int left =0,right = n;
//     while (left<right)
//     {
//         ans+=pow((arr[left]-arr[right]),2);
//         right--;
//         ans+=pow((arr[left]-arr[right]),2);
//         left++;
//     }
//     cout<<ans;
// }

// p4447
// 1.从小打到大排序
// 2.所有的都遍历一遍看是否连续(60分?)明白了:1 2 3 2 3 4过不了

// long long arr[10000000];
// long long ans = 0xffffffff;
// int main()
// {
//     long long n,count = 1;
//     cin>>n; 
//     for(long long i =0;i<n;i++)
//         cin>>arr[i];
//     sort(arr,arr+n);
//     for(long long i =1;i<n;i++)
//     {
//         if(arr[i]==arr[i-1]+1)count++;
//         else{
//             if(count<ans)ans = count;
//             count =1;
//         }
//     }
    
//     if(count<ans)ans = count;
        
//     cout<<ans;
// }

// p1080

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值