补一些题...

ABC365的C - Transportation Expenses 

二分,给定一个上限m,那么l=0,r=m。每次得到中间的mid值,然后遍历数组,sum+=min(mid,a[i])得到当前mid这时候的sum值,看这个值跟m比大小,如果小,那么说明l可以变成mid再往前走,如果大了,那就r变成mid+1,再制造出来的mid就会小了。当然还需要看一下全部a[i]加起来的和跟m比一下大小,如果这个sum小了,那就可以是无限大的了。

#include<bits/stdc++.h>
using namespace std;
const int N = 100010;
typedef long long ll;
bool cmp(int  a,int b)
{
	return a>b;
}
void solve() {
   ll sum1=0,sum2=0,n,m;cin>>n>>m;
   vector<ll> a(n+1,0);
   for(ll i=1;i<=n;i++)
   	{cin>>a[i];sum1+=a[i];}
   ll l=0,r=m,mid=m/2;
   while(l<r)
   {
   		mid=(l+r)/2;
   		for(int i=1;i<=n;i++)
   		{
   			sum2+=min(mid,a[i]);
   		}
   		if(sum2<=m){l=mid+1;}
   		else {r=mid;}
   		sum2=0;
   }
   if(sum1<=m){cout<<"infinite"<<endl;}
   else{cout<<r-1<<endl;}
   return ;
}
int main(){
  int T;cin >> T;
    while(T--){
        solve();
    }
    return 0;
}

CF Round963B. Parity and Sum

唉,气,vector居然比直接开数组要慢,直接TLE,题意简单,首先一种特殊情况是全部都是奇数或者偶数,这种直接return0;就行,然后是大头因为每次奇偶相加都是奇数,所以最后必然全是奇数。那么找到奇数最大数,和偶数最大数,尽量做到一次就能造出最大的maxi,啊对还要注意的一个点是要sort一下从小到大遍历,因为有可能maxi加前面小的加着加着可能就大了,但是遇到第一次m比v[i]小了之后,就可以直接把最大的那个偶数给加上去了,即那一步直接替换成跟最大偶数的交换。

#include<bits/stdc++.h>
using namespace std;
const int N = 2e5+7;
typedef long long ll;
bool cmp(int  a,int b)
{
    return a>b;
}
void solve() {
   int n,ans=0,flag1=0,flag2=0,cnt=0;cin>>n;
   ll v[n+10];
   //vector<ll> id(N,0);
   int k=1;ll maxi=0,maxi2=0,pos=0;
   for(int i=1;i<=n;i++)
   {
    cin>>v[i];
    if(v[i]%2==0){cnt++;if(maxi2<v[i]){maxi2=v[i];pos=i;}}
    else {maxi=max(maxi,v[i]);}
    if(i==1){flag1=v[i]%2;}
    else {if(v[i]%2!=flag1){flag2=1;}}
   }
   if(!flag2){cout<<0<<endl;return ;}
   int m=1;
   sort(v+1,v+1+n);
   //sort(id.begin()+1,id.begin()+k);
   //for(int i=1;i<k;i++)cout<<id[i]<<' ';
   //cout<<maxi<<endl;
   //if(maxi<maxi2){cnt++;maxi=maxi+maxi2;maxi+=maxi2;v[pos]=maxi;}
   //if(maxi<maxi2){maxi=maxi+maxi2;cnt++;}
   for(int i=1;i<=n;i++)
   {
   		//if(i==pos){if(maxi<maxi2){cnt++;maxi=maxi+maxi2;maxi+=maxi2;v[pos]=maxi;}continue;}
        if(v[i]<maxi&&v[i]%2==0){v[i]=v[i]+maxi;maxi=v[i];}
        else if(v[i]%2==0&&v[i]>maxi){cnt++;maxi=v[i]+maxi2+maxi;}
	}
   cout<<cnt<<endl;
}
int main(){
    int T;cin >> T;
    while(T--){
        solve();
    }
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值