P1023 税收与补贴问题

假装没事ソ 提交于 2020-02-02 09:50:18

一、第一印象

这道题一开始真心没看懂啥意思,当时自己想的是利润是一个一元二次方程。但是没想通为什么政府的税收可以影响整个曲线的对称轴。感觉添加税收整个曲线的利润增加才对,应该不会改变他的形态。
后来想通,税收是加在单价上的,虽然每个阶段的单价都加上同样的税收,但是由于每个单价对应的销售量不同,所以利润曲线会有变化。
想到这就想通了,开始解题:

二、分析

这个题其实就是在不停的解方程,获得一个范围,最后通过范围来得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;

这样非常索引好找,而且占用空间少。

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!