程序控

IPPP (Institute of Penniless Peasent-Programmer) Fellow

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: :: 管理 ::

Problem
问题

The well-known physicist Alfred E Neuman is working on problems that involve multiplying polynomials of x and y. For example, he may need to calculate
著名的物理学家纽曼(译注: 杜撰人名 )正在研究的问题中需要计算多项式的乘积,他可能需要计算:

(-x8y+9x3-1)·(x5y+1+x3)

getting the answer
算得结果:

-x13y2-x11y+8x8y+9x6-x5y+x5y2+8x3+x3y-1+y

Unfortunately, such problems are so trivial that the great man's mind keeps drifting off the job, and he gets the wrong answers. As a consequence, several nuclear warheads that he has designed have detonated prematurely, wiping out five major cities and a couple of rain forests.
不幸的是,这个问题太烦人了,而这位牛B物理学家在解题的时候脑子里跑了火车,结果解错了。后果很严重,几个核弹头将被提前发射,将几个大城市和大面积的雨林夷为平地。

You are to write a program to perform such multiplications and save the world.
你来设计一个程序执行该乘积运算,以拯救世界。

 

Input
输入

The file of input data will contain pairs of lines, with each line containing no more than 80 characters. The final line of the input file contains a # as its first character. Each input line contains a polynomial written without spaces and without any explicit exponentiation operator. Exponents are positive non-zero unsigned integers. Coefficients are also integers, but may be negative. Both exponents and coefficients are less than or equal to 100 in magnitude. Each term contains at most one factor in x and one in y.
输入的数据每两行为一组,每行都不会超过80个字母。最后一行用#号作为其第一个字母。每个输入的多项式数据中都不包含任何空格和幂运算符。指数为非0的无符号正数。系数也是整数,但可能为负。指数和系数的数量级都小于或等于100。多项式中的每一项最多有两个因子x和y。

 

Output
输出

Your program must multiply each pair of polynomials in the input, and print each product on a pair of lines, the first line containing all the exponents, suitably positioned with respect to the rest of the information, which is in the line below.
你要写一个程序来计算输入的每两行多项式的乘积,并将结果用两行打印出来。第一行打印所有的指数,其位置要和下面的一行对应。

The following rules control the output format:
输出要遵循下列格式要求。

  1. Terms in the output line must be sorted in decreasing order of powers of x and, for a given power of x, in increasing order of powers of y.
    输出的各项必须按x指数的降序排列,若相等则按y指数的升序排列。
  2. Like terms must be combined into a single term. For example, 40x2y3 - 38x2y3 is replaced by 2x2y3.
    必须合并同类项,比如:40x2y3 - 38x2y3应合并为2x2y3
  3. Terms with a zero coefficient must not be displayed.
    不要打印0系数项。
  4. Coefficients of 1 are omitted, except for the case of a constant term of 1.
    不要打印系数1,除非是常数项。
  5. Exponents of 1 are omitted.
    忽略为1的指数。
  6. Factors of x0 and y0 are omitted.
    若因子(x或y)的指数为0,则忽略该因子。
  7. Binary pluses and minuses (that is the pluses and minuses connecting terms in the output) have a single blank column both before and after.
    二元运算符加号和减号(即两项中间的加减号)的前后要有空格。
  8. If the coefficient of the first term is negative, it is preceded by a unary minus in the first column, with no intervening blank column. Otherwise, the coefficient itself begins in the first output column.
    如果第一项的系数为负,则需在行首打印一元运算符负号,后面没有空格。如果第一项系数为正,则直接从行首开始打印该项。
  9. The output can be assumed to fit into a single line of at most 80 characters in length.
    输出可以认为不会超过一行80个字符长度。
  10. There should be no blank lines printed between each pair of output lines.
    输出两行结果之间不要有空行。
  11. The pair of lines that contain a product should be the same length--trailing blanks should appear after the last non-blank character of the shorter line to achieve this.
    输出的两行乘积结果应该有相同的长度,较短的一行应在行尾填充空格使之对齐。

 

Sample Input
输入示例

-yx8+9x3-1+y
x5y+1+x3
1
1
#

 

Sample Output
输出示例

  13 2    11      8      6    5     5 2     3    3
-x  y  - x  y + 8x y + 9x  - x y + x y  + 8x  + x y - 1 + y

1

 

Analysis
分析

没啥好分析的,极其无聊的题目,按要求做就可以了。觉得花这么长时间,翻译这么多,还写了这么多代码,太不值了!

只是要注意处理系数为0和乘积为0的情况就好。

 

Solution
解答

#include <algorithm>
#include <iostream>
#include <string>
#include <vector>
#include <stdio.h>
using namespace std;
//表示多项式中各项的结构体
struct TERM {
	//成员分别为系数,x指数和y指数
	int cof; int xe; int ye;
	//构造函数,按参数初始化变量
	TERM (int c, int x, int y) : cof(c), xe(x), ye(y) {}
};
//比较两项指数的大小,用于排序和合并同类项
bool GreaterTerm(const TERM &t1, const TERM &t2) {
	return (t1.xe > t2.xe || (t1.xe == t2.xe && t1.ye < t2.ye));
}
//解析输入多项式字符串的函数
void ParsePolynomial(char *pStr, vector<TERM> &Terms) {
	//循环处理每一项
	for (int nNum; *pStr != 0;) {
		//确定该项的正负号,并初始化项结构体
		TERM Term(*pStr == '-' ? -1 : 1, 0, 0);
		//如果前面有符号,则指针向后移位
		pStr += (*pStr == '-' || *pStr == '+') ? 1 : 0;
		//如果系数为0,则跳过整项
		if (*pStr == '0') {
			for(++pStr; *pStr != '\0' && *pStr != '+' && *pStr != '-'; ++pStr);
			continue;
		}
		//读取符号后面的系数
		for (nNum = 0; isdigit(*pStr); nNum = nNum * 10 + *pStr++ - '0');
		//如果系数不为0,则乘到项结构体的系数中去(保留原符号)
		for (Term.cof *= (nNum == 0) ? 1 : nNum; isalpha(*pStr);) {
			//循环读取两个变量的指针(如果存在),先确定是x还是y的指数
			int *pe = (*pStr == 'x') ? &Term.xe : &Term.ye;
			//读取后面的指数
			for (; isdigit(*++pStr); *pe = *pe * 10 + *pStr - '0');
			//没有指数即指数为1
			*pe = (*pe == 0) ? 1 : *pe;
		}
		//将新项结构体加入数组
		Terms.push_back(Term);
	}
}
//主函数
int main(void) {
	//循环读入所有输入的数据,遇到#号结束
	for (string str1, str2; cin >> str1 && str1 != "#"; ) {
		cin >> str2;
		if (str1.empty() || str2.empty()) continue;
		const int nMaxLen = 100;
		char szBuf1[nMaxLen], szBuf2[nMaxLen];
		vector<TERM> Poly1, Poly2, Result;
		//转存两个字符串以备解析多项式
		strcpy(szBuf1, str1.c_str());
		strcpy(szBuf2, str2.c_str());
		//解析两个多项式字符串
		ParsePolynomial(szBuf1, Poly1);
		ParsePolynomial(szBuf2, Poly2);
		vector<TERM>::iterator i, j;
		//执行多项式乘法
		for (i = Poly1.begin(); i != Poly1.end(); ++i) {
			for (j = Poly2.begin(); j != Poly2.end(); ++j) {
				TERM Term(i->cof * j->cof, i->xe + j->xe, i->ye + j->ye);
				Result.push_back(Term);
			}
		}
		//按项指数排序
		sort(Result.begin(), Result.end(), GreaterTerm);
		fill(&szBuf1[0], &szBuf1[nMaxLen], ' ');
		fill(&szBuf2[0], &szBuf2[nMaxLen], ' ');
		int nPos = 0;
		//查找同类项
		for (i = Result.begin(); i != Result.end(); ++i) {
			//合并后面的同类项(如果存在)
			for (j = i + 1; j < Result.end() &&
				i->xe == j->xe && i->ye == j->ye;) {
				i->cof += j->cof;
				j = Result.erase(j);
			}
			//如果该项的系数不为0,则将其输出
			if (i->cof != 0) {
				if (nPos > 0) { //不是第一项,输出中间的运算符
					++nPos;	//输出运算符前面的空格
					szBuf2[nPos++] = i->cof > 0 ? '+' : '-';
					szBuf2[nPos++] = ' ';
				}
				else { //第一项,输出前面的符号(如果为负)
					szBuf2[0] = '-';
					nPos += (i->cof < 0);
				}
				//如果系数(绝对值)不为1或xy指数都为0,则输出系数
				i->cof = abs(i->cof);
				if (i->cof != 1 || (i->xe == 0 && i->ye == 0)) {
					nPos += sprintf(&szBuf2[nPos], "%d", i->cof);
					//给sprintf擦屁股
					szBuf2[nPos] = ' ';
				}
				//如果x指数不为0,则输出x
				if (i->xe > 0) {
					szBuf2[nPos++] = 'x';
					if (i->xe > 1) {
						nPos += sprintf(&szBuf1[nPos], "%d", i->xe);
						szBuf1[nPos] = ' ';
					}
				} //同上
				if (i->ye > 0) {
					szBuf2[nPos++] = 'y';
					if (i->ye > 1) {
						nPos += sprintf(&szBuf1[nPos], "%d", i->ye);
						szBuf1[nPos] = ' ';
					}
				}
			}
		}
		//如果没有输出任何项,则多项式乘积为0
		if (nPos == 0) {
			szBuf2[nPos++] = '0';
		}
		//为多项式乘积字符串划结束符并输出
		szBuf1[nPos] = szBuf2[nPos] = '\0';
		cout << szBuf1 << '\n' << szBuf2 << endl;
	}
	return 0;
}

posted on 2010-08-18 01:57  Devymex  阅读(1376)  评论(0编辑  收藏  举报