UVa 537 Artificial Intelligence

题目描述

题目要求从文本中提取两个物理量(电压 UUU、电流 III、功率 PPP)的值,并计算第三个未知量。公式为 P=U×IP = U \times IP=U×I。输入中包含可能的前缀(m\texttt{m}m 毫、k\texttt{k}k 千、M\texttt{M}M 兆)。输出计算结果,保留两位小数。

输入格式

第一行一个整数 nnn,表示测试用例的数量。每个测试用例一行文本,包含恰好两个数据字段(格式如 P=100WU=200VI=4.5A),以及一些额外单词。输入保证等号只在数据字段中出现。

输出格式

对于每个测试用例,输出 Problem #k,然后输出计算结果(格式如 P=900.00WI=0.45AU=1250000.00V),最后输出一个空行。

样例

输入

3
If the voltage is U=200V and the current is I=4.5A, which power is generated?
A light-bulb yields P=100W and the voltage is U=220V. Compute the current, please.
bla bla bla lightning strike I=2A bla bla bla P=2.5MW bla bla voltage?

输出

Problem #1
P=900.00W

Problem #2
I=0.45A

Problem #3
U=1250000.00V

题目分析

本题的核心是从文本中解析出数据字段,并根据公式计算未知量。

解析方法

对于每个数据字段,定位 P=U=I=,然后提取等号后面的数字和单位。数字可能包含正负号、小数点。单位可能带有前缀(mkM)。将数值转换为标准单位(即乘以相应前缀因子)。

计算

  • 若已知 PPPUUU,则 I=P/UI = P / UI=P/U
  • 若已知 PPPIII,则 U=P/IU = P / IU=P/I
  • 若已知 UUUIII,则 P=U×IP = U \times IP=U×I

输出

按指定格式输出,保留两位小数。

复杂度分析

每个测试用例只需解析一行文本,O(L)O(L)O(L)

代码实现

// Artificial Intelligence?
// UVa ID: 537
// Verdict: Accepted
// Submission Date: 2016-08-10
// UVa Run Time: 0.000s
//
// 版权所有(C)2016,邱秋。metaphysis # yeah dot net

#include <bits/stdc++.h>

using namespace std;

int main(int argc, char *argv[])
{
    cin.tie(0); cout.tie(0); ios::sync_with_stdio(false);

    string line;
    getline(cin, line);
    int n = stoi(line);

    for (int cases = 1; cases <= n; cases++)
    {
        cout << "Problem #" << cases << '\n';

        vector<char> keys = {'P', 'U', 'I'};
        map<char, double> values = {{'P', -1.0}, {'U', -1.0}, {'I', -1.0}};
        map<char, double> units = {{'m', 0.001}, {'k', 1000.0}, {'M', 1000000.0}};

        getline(cin, line);
        for (auto key : keys)
        {
            string target = "=";
            target.insert(target.begin(), key);

            int start = line.find(target);
            if (start != line.npos)
            {
                string block;
                for (int i = start; i < line.length(); i++)
                {
                    if (!isblank(line[i]))
                        block += line[i];
                    else
                        break;
                }

                string number;
                for (int i = 2; i < block.length(); i++)
                    if (isdigit(block[i]) || block[i] == '.' || block[i] == '+' || block[i] == '-')
                        number += block[i];
                    else
                        break;

                values[key] = stod(number);
                for (auto unit : units)
                    if (block.find(unit.first) != block.npos)
                    {
                        values[key] *= unit.second;
                        break;
                    }
            }
        }

        if (values['P'] >= 0 && values['U'] > 0)
            cout << "I=" << fixed << setprecision(2) << (values['P'] / values['U']) << "A\n\n";
        else if (values['P'] >= 0 && values['I'] > 0)
            cout << "U=" << fixed << setprecision(2) << (values['P'] / values['I']) << "V\n\n";
        else
            cout << "P=" << fixed << setprecision(2) << (values['U'] * values['I']) << "W\n\n";
    }
    
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值