537 - Artificial Intelligence?

题意:
给定一段描述, 从中分析出所给的条件是 P、U、I 中的某两项, 然后根据公式 P=U*I 计算出所缺的另一项.

思路:
1. 先在字符串中分别查找 P=、U=、I=;
(1). 若找到 P=, 则往后遍历, 直至找到第一个 W(P的单位) 为止, 然后往前一位看是否为 W 的前缀 m, 若是, 则取为 1.0 / 1000;
(2). 若找到 U=, 则往后遍历, 直至找到第一个 V(U的单位) 为止, 然后往前一位看是否为 V 的前缀 k, 若是, 则取为 1000;
(3). 若找到 I=, 则往后遍历, 直至找到第一个 A(I的单位) 为止, 然后往前一位看是否为 A 的前缀 M, 若是, 则取为 1000000;

2. 若找到 P、U, 则使用公式 I = P/U; 若找到 P、I, 则使用公式 U = P/I; 若找到 U、I, 则使用公式 P = U*I.

要点:
1. %.2f 输出两位小数.

2. atof 转 string 为 double.

3. 表达式的结尾下标就是从P=、U=、V=找到其相应的单位(W、V、A),不能是说找到第一个空格,否则下面的例子会出错: 
I=-1e-2A and U=2e3V
xx xx x I=0.0000000000000001MA yy yy U=1000000000000000.0000000mV zz
U=200VI=4.5A.

4. 1/1000 会返回0, 即使写在 double(1/1000) 也一样; 若想得到 0.001, 必须写成 1.0/1000.

5. 不能直接写 string head = 'P' + "="; 也不能写成 string head = "p" + "="; 因为 'P' 是 char 类型, "="是const char[2] 类型(注意不是string类型), 而这两者都是没有重载.

题目:
http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&category=96&page=show_problem&problem=478

代码:

# include <iostream>
# include <string>
# include <cstdio>
# include <cstring>
# include <vector>
# include <algorithm>
# include <stdlib.h> // atof
using namespace std;


// 根据一个表达式获取其单位前缀, 即表达式从后往前数一位, 如果是 m, k, M 就是有前缀, 否则返回 -1
double getPrefix(const string line, int lastPos){
	switch(line[lastPos-1]){
		case 'm':
			// 这里不能直接写成 1/1000, 否则会转化成 0, 导致好几次 WA, 必须直接写成 1.0/1000
			return 1.0/1000;			
		case 'k':
			return 1000;
		case 'M':
			return 1000000;
		default:
			return 1;
	}
}


// 获取 P, U, I 的值, 若未找到, 则返回 -1
double getConcept(const string line, char concept, char unit)
{
	// 这里不能直接写成 string head(concept);
	string head(1, concept);					
	head += "=";
        // string head = concept + "=";

	// 表达式的起始下标就是 P= 或 U= 或  I=
	size_t conceptHead = line.find(head);		
	if(conceptHead == string::npos){
		return -1;
	}

	// 表达式的结尾下标就是从 表达式起始 开始找到的第一个 unit
	size_t conceptTail = line.find(unit, conceptHead);   
	double prefix = getPrefix(line, conceptTail);

	string number;
	if(1 == prefix){			// 没有前缀
		number = line.substr(conceptHead+2, conceptTail-conceptHead-2);

	}else{						// 有前缀
		number = line.substr(conceptHead+2, conceptTail-conceptHead-3);
	}

	return atof(number.c_str()) * prefix;
}



// 根据读入的字符串获得结果
string getSolution(const string line)
{
	// 分别获取 P,U,I, 若不存在, 则返回 -1
	double P = getConcept(line, 'P', 'W');
	double U = getConcept(line, 'U', 'V');
	double I = getConcept(line, 'I', 'A');

	char solution[20];

	if(-1 == P){
		sprintf(solution, "P=%.2lfW", U*I);

	}else if(-1 == U){
		sprintf(solution, "U=%.2lfV", P/I);

	}else if(-1 == I){
		sprintf(solution, "I=%.2lfA", P/U);

	}else{
		return "error";
	}

	return solution;
}




int main(int argc, char const *argv[])
{
	#ifndef ONLINE_JUDGE
		freopen ("537_i.txt", "r", stdin);  
		freopen ("537_o.txt", "w", stdout); 
	#endif

    int caseNum = 0;
    cin >> caseNum;
    cin.ignore();		//  必须有这行,否则下面 getline 会读到空行

    for(int i=0; i<caseNum; i++){

    	string line;
    	getline(cin, line);

    	string solution = getSolution(line);

    	cout << "Problem #" << i+1 << endl 
    	     << solution << endl << endl;
    }


	return 0;
}

环境:C++ 4.5.3 - GNU C++ Compiler with options: -lm -lcrypt -O2 -pipe -DONLINE_JUDGE

你可能感兴趣的:(Artificial,Intelligence,537)