1 条题解

  • 2
    @ 2023-5-27 9:57:33

    思路

    ▶用结构体储存价格和对应销量,从成本价开始,价格每次增加1。输入过程若上下两行价格之差不为1则计算这两个价格的价格差和销量差,得到单价销量公差,逐个记录价格及销量。

    ▶输入完成后,还要记录超过输入的最大价格之后每上涨1元的价格和销量,直到销量≤0不再记录。

    ▶题目要求的无非是一个数字(税收或补贴,负数表示税收,正数补贴)。此时政府预期价+这个数字的获利 ≥ 其他价格+这个数字的获利。要求输出绝对值最小的,因此这个数字(代码中用sub表示)从1开始遍历,正数负数各遍历一次,某次利润最大时刚好是政府预期价+(或-)sub,则输出sub

    #include<iostream>
    using namespace std;
    #define maxn 100000
    #define INF 0x3f3f3f3f
    struct Info{
    	int p, n; //价格,销量 
    }info[maxn];
    int main()
    {
    	int exp, dn;
    	cin >> exp;
    	int i = 0;
    	while(cin >> info[i].p >> info[i].n ){
    		if(info[i].p == -1 && info[i].n == -1) { i--; break;}
    		if(i > 0 && info[i].p - info[i-1].p != 1){ //价格差不为1 
    			int d = (info[i-1].n-info[i].n) / (info[i].p-info[i-1].p); //计算单价销量公差 
    			int sp = info[i-1].p, lp = info[i].p, j;
    			for(j = 1; j <= lp - sp; j++){
    				info[i-1+j].p = info[i-1].p + j;
    				info[i-1+j].n = info[i-1].n - d*j;
    			}
    			i += j-2;
    		}
    		i++;
    	}
    	cin >> dn;
    	while(info[i].n - dn > 0){ //销量不为0则一直记录 
    		i++;
    		info[i].p = info[i-1].p + 1;
    		info[i].n = info[i-1].n - dn;
    	}
    	int sub, profit,  price;
    	bool find = false; //作为有否找到一个数字sub使预期价+sub获利最大的标志 
    	for(sub = 1; sub < maxn; sub++){
    		int max = -INF;
    		for(int j = 1; j <= i; j++){
    			profit = (info[j].p - info[0].p + sub) * info[j].n;
    			if(profit >= max){ max = profit; price = info[j].p;}
    		}
    		if(price == exp) { find = true; cout << sub << endl; break;}
    		max = -INF;
    		for(int j = 1; j <= i; j++){			
    			profit = (info[j].p - info[0].p - sub) * info[j].n;
    			if(profit >= max){ max = profit; price = info[j].p;}
    		}
    		if(price == exp) { find = true; cout << "-" << sub << endl; break;}
    	}
    	if(!find) cout << "NO SOLUTION" << endl; 
    	return 0;
    }
    
    • 1

    [普及~提高][NOIP2000 普及组] 税收与补贴问题

    信息

    ID
    1752
    时间
    1000ms
    内存
    256MiB
    难度
    2
    标签
    递交数
    68
    已通过
    43
    上传者