HDU2214 函数图像

函数图像

Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 401    Accepted Submission(s): 86


Problem Description
在数学中,我们经常会遇到,关于函数的问题,在画一些函数的图像的时候,最长用的方法就是“描点法”。

“描点法” 的具体步骤如下:
>  计算出函数在某些特定点的值
>  在坐标系中标记出这些点
>  用平滑的曲线连接这些点

但是,在实际的操作中,我们会发现,前两部的计算量还是相当大的,所以,我们想编写一个程序,能够在一个坐标系中直接的画出各点。

为了简化这个问题,给出如下y 关于x 的函数表达式

  y=a1x^b1+a2x^b2+a3x^b3+...+anx^bn

表达式不超过5项,并且 其中每项的系数 -10 < a <10 , x的指数 0 <= b < 5 
表达式中,所有的字符串都是以 ”y=” 开始的 ,在之后的字符串中只含有x ,+ , - , 0~9 这些字符,不含有空格。无非法表达式输入。

特别的:
当x 的指数为1时,省略指数,    例如: y = 2x^1   应表示为 y = 2x
当x 的指数为0时,省略指数和x,   例如: y = 3x^3+2x^0   应表示为 y = 3x^3+2
当x 的系数为负时,     例如: y = 3x^2 + (-1) x 应表示为 y = 3x^2 – x , y = 2x + (-2)   应表示为 y = 2x - 2
在如下坐标系中画出,x属于[-30,30] 所对应y属于[-30,30]的图像。
 

Input
多组数据输入,每组数据的第一行给出一个n (1<=n <= 26) ,接下来的n行,每行有一个函数的表达式。
 

Output
对于每组输入数据,在第一行输出,”Case:#” ,# 代表当前的组号。 画出该函数的图像 x取值[-30,30]时, y在 [-30,30]内的点 。对于给出的n个表达式,依次用字母a-z表示每个函数图像上的的所有点。两个图像的交点 或者 图像与坐标轴的交点 用 ‘.’ 表示。输出格式如下所示。各组之间无空行。
 

Sample Input
    
    
2 y=-x-1 y=x^4+1-x^3
 

Sample Output
    
    
Case:1 y^ | a | a | a | a | a b | a | a | a | a | a | a | a | a | a | a | a | a | a | a | a | a | b a | a | a | a | a | a b| a | a .b -----------------------------.+------------------------------> . x |a | a | a | a | a | a | a | a | a | a | a | a | a | a | a | a | a | a | a | a | a | a | a | a | a | a | a | a | a
 


题意分析:相对来说,这种题目属于简单题,不过代码写出来却很闹心,因为数据处理的时候有点麻烦。对于输入的字符串,只可能存在 +,-,^,x,0-9这几个字符,不存在括号,而且根据题意可以发现,表达式最多含有5个(就是通过+和-号进行分割后含有几项)。

先对表达式进行每一项分割,然后求值,题目要求是-30到30的,对于每一次对应的输入,输出对应的字符即可。有一组特殊的测试数据:y=0;多注意下。

#include <iostream>
#include <algorithm>
#include <string>
#include <cmath>
#include <cstdio>
#include <cstring>
#define ll long long
#define PI acos(-1)
#define M(n, m) sizeof(n, m, sizeof(n));
const int INF = 2 << 30;
const int maxn = 1e5 + 100;
using namespace std;

char Map[100][100];
int n;
int a[101];

void Init()
{
    memset(Map, ' ', sizeof(Map));
    int x, y;
    x = y = 1;
    for (int i = -30; i <= 30; i ++, x ++)
    {
        y = 1;
        for (int j = -30; j <= 30; j ++, y ++)
            if (i == 0 && j == 0)
                Map[x][y] = '+';
            else if (i == 0)
                Map[x][y] = '|';
            else if (j == 0)
                Map[x][y] = '-';
            else
                Map[x][y] = ' ';
    }
    Map[30][0] = 'y';
    Map[31][0] = '^';
    Map[62][31] = '>';
    Map[62][32] = 'x';
}


// 这个c是符号
int Judge(string str, char c, int x)
{
    // 先判断是否有x
    bool flag = false;
    for (int i = 0; i < str.size(); i ++)
        if (str[i] == 'x')
        {
            flag = true;
            break;
        }
    if (!flag)
    {
        // 没有的话,直接转化为整数
        int sum = 0;
        for (int i = 0; i < str.size(); i ++)
            sum = sum * 10 + (str[i] - '0');
        if (c == '-')
            return sum * (-1);
        else
            return sum;
    }
    else
    {
        // 有x的时候
        // 判断是否含有^
        bool f = false;
        for (int i = 0; i < str.size(); i ++)
            if (str[i] == '^')
            {
                f = true;
                break;
            }
        if (!f)
        {
            // 不存在^, x在最后一位,所以直接遍历到x-1
            int sum;
            if (str[0] == 'x')
                sum = 1;
            else
                sum = 0;
            for (int i = 0; i < str.size() - 1; i ++)
                sum = sum * 10 + str[i] - '0';
            if (c == '-')
                return sum * (-1) * x;
            else
                return sum * x;
        }
        else
        {
            // 存在^
            int sum, i;
            if(str[0] == 'x')
                sum = 1;
            else
                sum = 0;
            for ( i = 0; i < str.size() && str[i] != 'x'; i ++)
                sum = sum * 10 + str[i] - '0';
            int sum2 = 0;
            for (i += 2; i < str.size(); i ++)
                sum2 = sum2 * 10 + str[i] - '0';
            if (c == '-')
                return (-1) * sum * pow(x, sum2);
            else
                return sum * pow(x, sum2);
        }
    }
}

// 这个c用来输出
void Change(string str, char c)
{
    for (int i = -30; i <= 30; i ++)
    {
        int sum = 0;
        if (str[0] == '-')
        {
            // 开头是负号
            string s;
            s.clear();
            char x;
            x = str[0];
            for (int j = 1; j < str.size(); j ++)
            {
                if (str[j] == '-' || str[j] == '+')
                {
                    sum += Judge(s, x, i);
                    s.clear();
                    x = str[j];
                    continue;
                }
                s += str[j];
            }
            sum += Judge(s, x, i);
        }
        else
        {
            // 开头没有负号
            string s;
            s.clear();
            char x;
            x = '+';
            for (int j = 0; j < str.size(); j ++)
            {
                if (str[j] == '-' || str[j] == '+')
                {
                    sum += Judge(s, x, i);
                    s.clear();
                    x = str[j];
                    continue;
                }
                s += str[j];
            }
            sum += Judge(s, x, i);
        }
//        cout << sum << endl;
        // 可以会出现覆盖或者相交
        if (sum >= -30 && sum <= 30)
        {
//            cout << i + 30 + 1 << " " << sum << endl;
//            cout << i + 30 + 1 << " " << sum + 30 + i << endl;
            int x = i + 30 + 1;
            int y = 31 - sum;
            if (x == 0 || y == 0)
                Map[x][y] = '.';
            else if (Map[x][y] != ' ')
                Map[x][y] = '.';
            else
                Map[x][y] = c;
        }

    }
}
string str;
int main()
{
//    freopen("out.txt", "w", stdout);
    int num = 0;
    while(cin >> n)
    {
        Init();
        for (int i = 0; i < n; i ++)
        {
            cin >> str;
            // 去除开头的y=
            string s;
            s.clear();
            for (int j = 2; j < str.size(); j ++)
                s += str[j];
            Change(s, i + 'a');
        }
        printf("Case:%d\n", ++num);

        for (int j = 0; j < 62; j ++, cout << endl)
            for (int i = 1; i <= 62; i ++)
            {
                if (i == 62)
                {
                    if (Map[i][j] == 'x' || Map[i][j] == '>')
                        cout << Map[i][j];
                }
                else
                    cout << Map[i][j];
            }
    }
    return 0;
}

/*
1
y=x^4+1-x^3
*/


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值