一、第一印象
这道题一开始真心没看懂啥意思,当时自己想的是利润是一个一元二次方程。但是没想通为什么政府的税收可以影响整个曲线的对称轴。感觉添加税收整个曲线的利润增加才对,应该不会改变他的形态。
后来想通,税收是加在单价上的,虽然每个阶段的单价都加上同样的税收,但是由于每个单价对应的销售量不同,所以利润曲线会有变化。
想到这就想通了,开始解题:
二、分析
这个题其实就是在不停的解方程,获得一个范围,最后通过范围来得ans。
(31-28+x)*110>=(28-28+x)*130
(31-28+x)*110>=(29-28+x)*125
(31-28+x)*110>=(30-28+x)*120
(31-28+x)*110>=(32-28+x)*95
1)所以首先要先将没有的**点**,插值给补起来。(因为题里面说了相邻两点之间存在线性关系)。
2)之后用循环,把每一个方程式算出来,对边界进行筛选。
3)最后根据情况输出答案
三、代码
#include <iostream>
#include <cmath>
using namespace std;
int a = 0;
int d[100002][2] = {0};
int now = 0;
int k = 0;
int b = 0;
int down = 0;
int ye = 0;
int temp1 = 0, temp2 = 0;
void insert(int startX, int endX){
int tempX = startX + 1;
int tempY = tempX*k + b;
//政府的期望价格不一定在给出的数据里,所以要找出来,并且保存销量。
if(tempX == a)
ye = tempY;
d[now][0] = tempX;
d[now][1] = tempY;
now++;
tempX++;
while(tempX <= endX){
tempY = tempX * k + b;
//政府的期望价格不一定在给出的数据里,所以要找出来,并且保存销量。
if(tempX == a)
ye = tempY;
d[now][0] = tempX;
d[now][1] = tempY;
now++;
tempX++;
}
}
void get_k_b(int x1, int y1, int x2, int y2){
k = (y1 - y2) / (x1 - x2);
b = y1 - k * x1;
}
int main(){
cin>>a;
while(1){
cin>>temp1>>temp2;
//政府的期望价格不一定在给出的数据里,所以要找出来,并且保存销量。
if(temp1 == a)
ye = temp2;
if(temp1 == -1 && temp2 == -1)
break;
if(d[now-1][0] + 1 != temp1 && now != 0){
//获取线性系数的函数
get_k_b(d[now-1][0], d[now-1][1], temp1, temp2);
//插值的函数
insert(d[now-1][0], temp1);
continue;
}
d[now][0] = temp1;
d[now][1] = temp2;
now++;
}
cin>>down;
//做给定值之后的插值
int y = d[now-1][1] - down;
int x = d[now-1][0] + 1;
while(y >= 0){
if(a == x)
ye = y;
d[now][0] = x;
d[now][1] = y;
y -= down;
x++;
now++;
}
//到现在为止,以上已经把该有的所有值都补全了
//下面是求 补贴的范围了
double min = -1e9;
double max = 1e9;
int c = d[0][0];
double temp=0;
for(int i=0; i<now; i++){
//这个式子是用之前的不等式推导出来的
temp = ((d[i][0]-c)*d[i][1] + (c-a)*ye)*1.0/(ye-d[i][1]);
//对边界进行筛选
if(ye-d[i][1]<0 && max > temp)
max = temp;
if(ye-d[i][1]>0 && min < temp)
min = temp;
}
//此时[Min,Max]就是答案的范围,取绝对值最小的输出。
//Max>Min>0,答案为Min上取整
//Min<Max<0,答案为Max下取整
if(min>0)
printf("%d", (int)ceil(min));
else if(max<0)
printf("%d", (int)floor(max));
else if(min<=0 && max>=0)
cout<<0;
if(min>max)
cout<<"NO SOLUTION";
return 0;
}
四、不足
之前看题解的时候发现这种有关联的二维数据,可以直接用一维的数组表示。
d[x] = y;
这样非常索引好找,而且占用空间少。
来源:CSDN
作者:REAL_BJXLS
链接:https://blog.csdn.net/weixin_42059429/article/details/104129009