Luogu P1023 [NOIp2000提高组]税收与补贴问题 | 数学

题目链接

思路:列不等式组,然后解出不等式,得出答案的取值范围,最后取一个绝对值最小的答案就行了。

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
    using namespace std;
    const double eps=1e-8;
struct data
{
    int sj;//存售价 
    int xl;//存销量 
}s[110000];
int main()
{
    int k=0,w=0,yqj=0,flag=-1;//flag用来记录预期值在数组中的位置 
    double low=-1e7,up=1e7;//记录答案的取值范围 
    scanf("%d%d%d",&yqj,&s[0].sj,&s[0].xl);
    if(s[0].sj==yqj) flag=0;
    for(;;)
    {
        int t1=0,t2=0;
        scanf("%d%d",&t1,&t2);
        if(t1==-1&&t2==-1) break; 
        int js=(s[k].xl-t2)/(t1-s[k].sj);
        for(;;)//推导出输入中没给出的售价的销量 
        {
            k++;
            s[k].sj=s[k-1].sj+1;
            s[k].xl=s[k-1].xl-js;
            if(s[k].sj==yqj) flag=k;
            if(s[k].sj==t1) break;
        } 
    }
    scanf("%d",&w);
    for(;;)//将所有可以求出的售价的销量都推出来 
    {
        if(s[k].xl-w<0) break;
        k++;
        s[k].sj=s[k-1].sj+1;
        s[k].xl=s[k-1].xl-w;
        if(s[k].sj==yqj) flag=k;
    }
    if(flag==-1)//如果所有已知的销量的售价中没有预期价,则无解 
    {
        printf("NO SOLUTION"); 
        return 0;
    }
    for(int i=0;i<=k;i++)//开始解不等式组 
    {
        if(i==flag) continue;
        double u=(s[flag].sj-s[0].sj)*s[flag].xl-(s[i].sj-s[0].sj)*s[i].xl;//
        double v=s[i].xl-s[flag].xl;
        if(v<0) low=max(low,u/v);//记录 
           else up=min(up,u/v);
    }
    //输出答案 
    if(low>up) printf("NO SOLUTION");
     else if(low>0) 
             if(fabs(low-(int)(low))<eps) printf("%d",int(low));
             else printf("%d",int(low)+1);
         else if(up<0)
                     if(fabs(up-(int)(up))<eps) printf("%d",int(up));
                     else printf("%d",int(up)-1); 
                 else printf("0");
    return 0;
} 
原文地址:https://www.cnblogs.com/wozaixuexi/p/8467223.html