CODE[VS] 1016 税收与补贴问题
每样商品的价格越低,其销量就会相应增大。现已知某种商品的成本及其在若干价位上的销量(产品不会低于成本销售),并假设相邻价位间销量的变化是线性的且在价格高于给定的最高价位后,销量以某固定数值递减。(我们假设价格及销售量都是整数)
对于某些特殊商品,不可能完全由市场去调节其价格。这时候就需要政府以税收或补贴的方式来控制。(所谓税收或补贴就是对于每个产品收取或给予生产厂家固定金额的货币)
你是某家咨询公司的项目经理,现在你已经知道政府对某种商品的预期价格,以及在各种价位上的销售情况。要求你确定政府对此商品是应收税还是补贴的最少金额(也为整数),才能使商家在这样一种政府预期的价格上,获取相对其他价位上的最大总利润。
总利润 = 单位商品利润 * 销量
单位商品利润 = 单位商品价格 – 单位商品成本 (– 税金 or + 补贴)
输入的第一行为政府对某种商品的预期价,第二行有两个整数,第一个整数为商品成本,第二个整数为以成本价销售时的销量售,以下若干行每行都有两个整数,第一个为某价位时的单价,第二个为此时的销量,以一行-1,-1表示所有已知价位及对应的销量输入完毕,输入的最后一行为一个单独的整数表示在已知的最高单价外每升高一块钱将减少的销量。
输出有两种情况:若在政府预期价上能得到最大总利润,则输出一个单独的整数,数的正负表示是补贴还是收税,数的大小表示补贴或收税的金额最小值。若有多解,取绝对值最小的输出。
如在政府预期价上不能得到最大总利润,则输出“NO SOLUTION”.
31
28 130
30 120
31 110
-1 –1
15
4
这个题目刚拿过来就没读懂什么意思,后来一共提交了三次错误答案终于知道了这个的题目的意思。意思就是想办法让政府期望的那个值可以取得最大的总利润,通过一定的补贴或者是收一定的税。
拿题目所给例子来说明的话就是成本价位28,然后给出的最高价位31,31后每次涨价一元就会减少15个销量。而在31元之前,28和30之间,根据计算可得,当29元的时候可以卖出125.而当补贴4元的时候31元比其他价位卖出的总利润都要大。达到目的,所以为4.
具体算法思路见代码:
/************************************************************************* > File Name: 税收与补贴问题.cpp > Author: zhanghaoran > Mail: 467908670@qq.com > Created Time: 2015年05月22日 星期五 14时32分03秒 ************************************************************************/ #include <stdio.h> void swap(int &a, int &b){ int t =a; a = b; b =t; } int abs(int a){ if(a > 0) return a; else return -1*a; } //先简单的做两个求绝对值和交换的函数 int main(void){ int Exp; //政府期望值 int change_front, change_next; //达到最高值之前和最高值之后的每变化一元销量的变化 int a[100000], b[10000]; //用来存储输入的不定的价格和销量 int i = 0, j, k; int c[100000], d[100000]; //用来储存计算完毕的从成本价开始到销量为0时的价格和销量 int x, y, z, h,e; int temp; int add =0, reduce = 0; //分别表示补贴多少和收税多少 scanf("%d", &Exp); while(1){ scanf("%d %d", &a[i], &b[i]); if(a[i] == -1) break; else i ++; } for(j = 0; j < i; j ++){ for(k = 1; k < i - j; k ++){ if(a[k - 1] > a[k]){ swap(a[k - 1], a[k]); swap(b[k - 1], b[k]); //排序以防输入的数据不是升序排列的 } } } scanf("%d", &change_next); c[0] = b[0]; //c[0]先存储成本时的销量,因为成本价时的销量是无法计算出来的,要直接录入 x = 1; //x作为计数器 y = a[0]; //y为成本价 z = b[0]; //z位成本销量 for(j = 1; j < i; j++){ if(a[j] != y + 1){ //如果a[j]不是y+1的话,那么我们需要计算,否则直接从a和b数组中录入数据即可 change_front = abs(b[j] -z) / abs(a[j] - y); //算出达到最大值之前的变化规律并不断更新 temp = 1; while( y != a[j]){ c[x ++] = z - change_front * temp; //数组C做从成本价开始的每个小于最高价的价位的销量 temp ++; y ++; } z = b[j]; } else{ y = a[j]; z = b[j]; c[x ++] = b[j]; } } x --; //x作为计数器要自减一才为当前的c的长度 temp = 1; h = c[x]; //h储存最大值 while(c[x] > 0){ c[++ x] = h - change_next * temp; //当销量大于零时计算最大值以后的销量 temp ++; } for(j = 0; j < x; j++){ d[j] = a[0] ++; } for(j = 0; j < x; j++){ if(d[j] == Exp) e = c[j]; } for(j = 0; j < 100; j++){ int max; max = (Exp - d[0] + j) * e; int flag = 0; for(int r = 0; r < x; r++){ k = (d[r] - d[0] + j) * c[r]; if(k > max){ flag = 1; break;; //当补贴的时候如果存在比此时政府期望值更大的利润的话跳出循环,再更新补贴大小 ,下收税的循环也是一样 } } if(flag == 0){ add = j; break; } } for(j = -1; j > -100; j --){ int max = (Exp -d[0] + j) *e; int flag = 0; for(int r = 0; r < x; r ++){ k = (d[r] - d[0] + j)*c[r]; if(k > max){ flag = 1; break; } } if(flag == 0){ reduce = j; break; } } if(add == reduce && add == 0) printf("NO SOLUTION"); if(add == 0 && reduce != 0) printf("%d", reduce); if(add != 0 && reduce == 0) printf("%d", add); if(add != 0 && reduce != 0) printf("%d", add < reduce ? add : reduce); //输出的一些细节的问题。 return 0; }