A:水题,数据范围较小,直接暴力模拟。
1 class Solution { 2 public: 3 bool check(vector<int> a,int i,int j ){ 4 for(int k=i+1;k<=j;k++){ 5 if(a[k]<=a[k-1]){ 6 return false; 7 } 8 } 9 return true; 10 } 11 int maxAscendingSum(vector<int>& nums) { 12 int n=nums.size(); 13 int res=0; 14 for(int i=0;i<n;i++){ 15 for(int j=0;j<n;j++){ 16 int sum=0; 17 if(check(nums,i,j)){ 18 for(int k=i;k<=j;k++){ 19 sum+=nums[k]; 20 } 21 res=max(res,sum); 22 } 23 24 } 25 } 26 return res; 27 } 28 };
B:题目非常长,但是做法还是非常容易想到的, 给定两种订单,买和卖,当买>=卖的时候都可以完成这个和对应的订单。
然后数据范围为1e5,非常明显的堆的题目。
1 struct Node{ 2 int v,cnt; 3 bool operator< (const Node& t)const { 4 return v<t.v; 5 } 6 bool operator> (const Node& t)const { 7 return v>t.v; 8 } 9 }; 10 class Solution { 11 public: 12 const int mod=1e9+7; 13 int getNumberOfBacklogOrders(vector<vector<int>>& orders) { 14 priority_queue<Node,vector<Node>,less<Node>> q0; 15 priority_queue<Node,vector<Node>,greater<Node>> q1; 16 for(auto x:orders){ 17 int v=x[0],cnt=x[1],t=x[2]; 18 if(t==0){ 19 if(q1.size()==0){ 20 q0.push({v,cnt}); 21 continue; 22 } 23 while(cnt&&q1.size()&&q1.top().v<=v){ 24 auto tmp=q1.top(); 25 q1.pop(); 26 if(tmp.cnt<=cnt){ 27 cnt-=tmp.cnt; 28 }else{ 29 tmp.cnt-=cnt; 30 cnt=0; 31 q1.push(tmp); 32 } 33 } 34 if(cnt){ 35 q0.push({v,cnt}); 36 } 37 }else{ 38 if(q0.size()==0){ 39 q1.push({v,cnt}); 40 continue; 41 } 42 while(cnt&&q0.size()&&q0.top().v>=v){ 43 auto tmp=q0.top(); 44 q0.pop(); 45 if(tmp.cnt<=cnt){ 46 cnt-=tmp.cnt; 47 }else{ 48 tmp.cnt-=cnt; 49 cnt=0; 50 q0.push(tmp); 51 } 52 } 53 if(cnt){ 54 q1.push({v,cnt}); 55 } 56 } 57 } 58 long long res=0; 59 while(q0.size()){ 60 res+=q0.top().cnt; 61 q0.pop(); 62 res%=mod; 63 } 64 while(q1.size()){ 65 res+=q1.top().cnt; 66 q1.pop(); 67 res%=mod; 68 } 69 return res%mod; 70 } 71 };
C:给定数据长度和数组和,满足相邻元素差<=1,最大化nums [ index ]的值。
存在两种可能,sum非常的大足以覆盖整个数组
sum非常的小,只能覆盖一部分数组,其余的元素需要用0补足。
最开始我就只考虑到了第一种情况,推公式推了半天,然后做错了,浪费了非常多的时间。
nums[i]为正整数,所以首先全部赋值为1,然后从index开始向两边扩散。
1 class Solution { 2 public: 3 int maxValue(int n, int index, int maxSum) { 4 int l=index,r=index; 5 int res=1; 6 int rest=maxSum-n; 7 while(l>0||r<n-1){ 8 int len=r-l+1; 9 if(rest>=len){ 10 res++; 11 rest-=len; 12 }else{ 13 break; 14 } 15 l=max(l-1,0); 16 r=min(r+1,n-1); 17 } 18 res+=rest/n; 19 return res; 20 } 21 };
D:给定一个数组,一个区间,问这个数组内有多少对异或值在这个区间内。
数据范围为2e4,所以暴力是不行的, 可以使用字典树(题解)。
但是有些题解真的让我抓狂,真就别人看不懂的题解就是好的呗。
cnt整一条路上的cnt都会增加,如此的话就能够统计在这一棵子树共有多少个数了。
如果x某一位为1,high同一位也为1.
那么我们可以直接res+=cnt[son[p][1]],p=son[p][0]
加上在这一位上为1的数,再看这一位上位0的数。
共有四种情况,此处不一一列举了。
1 const int N=2e4+10; 2 int son[N*20][2],cnt[N*20],idx; 3 class Solution { 4 public: 5 void insert(int x) 6 { 7 int p=0; 8 for(int i=15;i>=0;--i) 9 { 10 int u = (x>>i)&1; 11 if(!son[p][u]) son[p][u]=++idx; 12 p=son[p][u]; 13 ++cnt[p]; 14 } 15 } 16 17 int query(int x,int hi){ 18 int p=0; 19 int res=0; 20 for(int i=15;i>=0;i--){ 21 int u=x>>i&1,h=hi>>i&1; 22 if(u==0&&h==0){ 23 p=son[p][0]; 24 } 25 if(u==0&&h==1){ 26 res+=cnt[son[p][0]]; 27 p=son[p][1]; 28 } 29 if(u==1&&h==0){ 30 p=son[p][1]; 31 } 32 if(u==1&&h==1){ 33 res+=cnt[son[p][1]]; 34 p=son[p][0]; 35 } 36 if(!p) return res; 37 } 38 return res; 39 } 40 int countPairs(vector<int>& nums, int low, int high) { 41 memset(son,0,sizeof son); 42 memset(cnt,0,sizeof cnt); 43 idx=0; 44 int res=0; 45 for(auto &i:nums) 46 { 47 res+=query(i,high+1)-query(i,low);//根据query,找出的是a^b<hi的b,所以得加1 48 insert(i); 49 } 50 return res; 51 52 } 53 };