PAT (Advanced Level) Practice

本文介绍了两个经典算法问题:A+B问题及其代码实现,包括输入处理、加法运算、符号判断等步骤;多项式相加问题,讨论了多项式相加的算法实现,涉及多项式项的读取、合并及输出。

A+B Format

#include <bits/stdc++.h>
using namespace std;

int integer1, integer2, numOfDigits, flag;

void scanAndAdd();
void isNegativeAndPrintSymbol();
void calculateNumOfDigits();
void determineFlag();
void print();

int main()
{
	scanAndAdd();
	isNegativeAndPrintSymbol();
	calculateNumOfDigits();
	determineFlag();
	print();
	return 0;
}

/* 1、处理输入并做加运算
2、判断是否为负数,若是则先输出负号并且取绝对值
3、判断该整数是几位数
4、设置一个标志变量,用来判断当前是否应该输出逗号,根据整数位数判断标志变量的初值
5、利用循环,从高位向低位,依次输出每一位的数值 */

void scanAndAdd() // 1、处理输入并做加运算
{
	scanf("%d %d", &integer1, &integer2);
	integer1 += integer2;
	// printf("integer1 = %d\n", integer1);
}

void isNegativeAndPrintSymbol() // 2、判断是否为负数,若是则先输出负号并且取绝对值
{
	if (integer1 < 0)
	{
		printf("-");
		integer1 = abs(integer1);
	}
}

void calculateNumOfDigits() // 3、判断该整数是几位数
{
	numOfDigits = 0;
	int temp = integer1;
	while (temp)
	{
		temp /= 10;
		++numOfDigits;
	}
	if (!integer1)
	{
		numOfDigits = 1;
	}
	// printf("numOfDigits = %d\n", numOfDigits);
}

void determineFlag() // 4、设置一个标志变量,用来判断当前是否应该输出逗号,根据整数位数判断标志变量的初值
{
	flag = numOfDigits % 3;
}

void print() // 5、利用循环,从高位向低位,依次输出每一位的数值
{
	int temp = pow(10, numOfDigits - 1);
	while (temp)
	{
		if (!flag)
		{
			flag = 3;
		}
		int digit = integer1 / temp;
		printf("%d", digit);
		--flag;
		integer1 %= temp;
		temp /= 10;
		if (!flag && temp)
		{
			printf(",");
		}
	}
}

A+B for Polynomials

#include <bits/stdc++.h>
using namespace std;

/* 1、map的erase用法(段错误) */

map<int, double, greater<int>> terms; //存放多项式的每一个项,键为指数,值为系数
int ka, kb;							  // A、B的项数

void copeWithPolynomialA();
void copeWithPolynomialB();
void copeWithTerms();
void print();

int main()
{
	/* 	map<int, int> m;
		m[3] = 2;
		m[4] = 3;
		m[2] = 7;
		m[0] = 10;
		m[11] = 1;
		m[12] = 12;
		m[0] = 2;
		for (auto a : m)
		{
			printf("%d %d\n", a.first, a.second);
		}
		printf("After erase\n");
		for (map<int, int>::iterator it = m.begin(); it != m.end(); ++it)
		{
			if (it->second == 2)
			{
				m.erase(it++->first);
			}
		}
		for (auto a : m)
		{
			printf("%d %d\n", a.first, a.second);
		}  */
	copeWithPolynomialA();
	copeWithPolynomialB();
	//copeWithTerms();
	print();
	return 0;
}

void copeWithPolynomialA()
{
	scanf("%d", &ka);
	for (int i = 0; i < ka; ++i)
	{
		// exponents and coefficients
		int exp;
		double coe;
		scanf("%d %lf", &exp, &coe);
		terms[exp] = coe;
	}
	/* //debug
	for (auto a : terms)
	{
		printf("%d %.1lf\n", a.first, a.second);
	} */
}

void copeWithPolynomialB()
{
	scanf("%d", &kb);
	for (int i = 0; i < kb; ++i)
	{
		// exponents and coefficients
		int exp;
		double coe;
		scanf("%d %lf", &exp, &coe);
		terms[exp] += coe;
		if (!terms[exp])
		{
			terms.erase(exp);
		}
	}
	/* // debug
	for (auto a : terms)
	{
		printf("%d %.1lf\n", a.first, a.second);
	} */
}

void copeWithTerms()
{
	if (terms.size())
	{
		for (map<int, double>::iterator it = terms.begin(); it != terms.end(); ++it)
		{
			if (it->second == 0)
			{
				terms.erase(it++->first);
			}
		}
	}
	/*
	 // debug
	 for (auto a : terms)
	 {
		 printf("%d %.1lf\n", a.first, a.second);
	 } */
}

void print()
{
	printf("%d", terms.size());
	if (terms.size())
	{
		for (map<int, double>::iterator it = terms.begin(); it != terms.end(); ++it)
		{
			printf(" %d %.1lf", it->first, it->second);
		}
		/* for (auto a : terms)
		{
			printf(" %d %.1lf", a.first, a.second);
		} */
	}
}

 调试过程中出现了段错误以及运行超时,其原因都是map的erase函数使用不当,上网查了一些资料,说是在erase一个记录的时候,系统会把相应的寄存器也删除?然后程序就会出现问题。

上述问题在循环外erase时应该不会发现异常,但是当erase函数是在循环内调用时,就会出现错误了。

现在太饿了,要去吃饭,所以循环内erase的使用方法还没搞懂,循环外erase可以放心大胆地使用。

时隔许久,才想起来这道题,发现第一次做的时候把这事想的太复杂了,我都没耐心看自己之前写的程序了,所以就重新写了一下,AC如下。 

#include <bits/stdc++.h>
using namespace std;
int main()
{
    double zhi_xi[1001] = {0};
    int N = 0;
    int sumOfXiangShu = 0;
    scanf("%d", &N);
    sumOfXiangShu = N;
    while (N--)
    {
        int zhishu = 0;
        double xishu = 0;
        scanf("%d %lf", &zhishu, &xishu);
        zhi_xi[zhishu] = xishu;
    }
    scanf("%d", &N);
    while (N--)
    {
        int zhishu = 0;
        double xishu = 0;
        scanf("%d %lf", &zhishu, &xishu);
        if (zhi_xi[zhishu])
        {
            zhi_xi[zhishu] += xishu;
            if (zhi_xi[zhishu])
            {
                continue;
            }
            else
            {
                sumOfXiangShu--;
            }
        }
        else
        {
            zhi_xi[zhishu] = xishu;
            sumOfXiangShu++;
        }
    }
    printf("%d", sumOfXiangShu);
    for (int i = 1000; i >= 0; --i)
    {
        if (zhi_xi[i])
        {
            printf(" %d %.1lf", i, zhi_xi[i]);
        }
        else
        {
            continue;
        }
    }
    return 0;
}

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

罗马尼亚硬拉

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值