P1023 税收与补贴问题 (数论&不等式)

题目传送门

题意:给定预期价格,求在此这价格使得其总利润最大的补贴或税金的绝对值最小的值。(PS:题面真的秀)

思路:貌似输入是默认按价格升序排列的,所以计算出所有价格的销售量,再从***到能到达的最高价进行遍历,暴力计算出ans的范围 [mn,mx]讨论mn,mx正负即可。

AC代码:

#include<bits/stdc++.h>
using namespace std;
const int N=1e5+5;
int a[N],ept,pr,cb,sum,now=0,b; //ept (expect)期待价格 pr(price) cb(成本) sum(销售量) now(当前价格) 
int main(){  //b(线性减少的销售量 
	cin>>ept>>pr>>sum,cb=pr;
	while(pr!=-1&&sum!=-1){ //默认价格按升序给出. 
		a[pr]=sum;
		for(int i=now+1;i<pr;i++)
			a[i]=a[i-1]+(sum-a[now])/(pr-now);//计算所有价格的销售量. 
		now=pr;
		cin>>pr>>sum;
	}
	cin>>b;
	while(a[now]>b)//计算最高价后递减的销售量. 
		now++,a[now]=a[now-1]-b;
	double mx=1e9,mn=-1e9; 
	for(int i=cb;i<=now;i++){
		int jg=a[i]-a[ept];
		if(jg){
		double ans=((ept-cb)*a[ept]-(i-cb)*a[i])*1.0/jg;//ans表示补贴 
		if(jg>0) mx=min(mx,ans);//判断符号是否是正 若为正则表示 ans<= ,否则是ans>= 
		else if(jg<0) mn=max(mn,ans);
		}	
	}
	if(mn>mx) puts("NO SOLUTION");
	else if(mn>0) printf("%d\n",(int)ceil(mn));
	else if(mx<0) printf("%d\n",(int)floor(mx));
	else puts("0");
	return 0;
}