2024/1/31学习总结

本文介绍了如何使用深度优先搜索解决自然数拆分问题,以及通过栈实现只包含加法和乘法的表达式求值,涉及C++代码示例。
摘要由CSDN通过智能技术生成

今日刷题    

自然数的拆分

自然数的拆分问题

题目描述

任何一个大于 $1$ 的自然数 $n$,总可以拆分成若干个小于 $n$ 的自然数之和。现在给你一个自然数 $n$,要求你求出 $n$ 的拆分成一些数字的和。每个拆分后的序列中的数字从小到大排序。然后你需要输出这些序列,其中字典序小的序列需要优先输出。

输入格式

输入:待拆分的自然数 $n$。

输出格式

输出:若干数的加法式子。

样例 

样例输入 
7

样例输出 

1+1+1+1+1+1+1
1+1+1+1+1+2
1+1+1+1+3
1+1+1+2+2
1+1+1+4
1+1+2+3
1+1+5
1+2+2+2
1+2+4
1+3+3
1+6
2+2+3
2+5
3+4


提示

数据保证,2<=n<=8。

思路:

看到本题,首先想到的是要使用深度优先搜索(dfs)。

注意:dfs中应包含两种情况,一种是选,另一种是不选。

AC代码如下(解析在代码中):

include<bits/stdc++.h>    //包含了大部分标准c++库的头文件

using namespace std;

int n,i;
int t=0,a[10000];
void dfs(int ans,int sum)    //考虑ans,还剩下sum需要划分
{
    if(sum==0)               //当没有余下的时候,即不需要进行划分,则输出答案
    {
        printf("%d",a[0]);
        for(i=1;i<t;i++)
        {
            cout<<"+"<<a[i];
        }
        cout<<endl;
        return;
    }          
 //如果要考虑这个数字比剩下需要划分的大,则没办法进行选择,return
 //如果这个数等于输入的数,则不成立(拆分至少要两个数),return              

    if(ans>sum||ans==n)
    {
        return ;
    }
    a[t++]=ans;
    dfs(ans,sum-ans);      //选ans
    t--;//回溯
    dfs(ans+1,sum);        //不选ans

}
int main()
{
    scanf("%d",&n);
    dfs(1,n);
    return 0;
}

表达式求值  

[NOIP2013 普及组] 表达式求值

题目背景

题目描述

给定一个只包含加法和乘法的算术表达式,请你编程计算表达式的值。

输入格式

一行,为需要你计算的表达式,表达式中只包含数字、加法运算符 `+` 和乘法运算符 `*`,且没有括号,所有参与运算的数字均为 $0$ 到   $2^{31}-1$ 之间的整数。  

输入数据保证这一行只有 `0123456789+*` 这 $12$ 种字符。

输出格式

一个整数,表示这个表达式的值。  

注意:当答案长度多于 $4$ 位时,请只输出最后 $ 4$ 位,前导 $ 0$ 不输出。



样例输入 

1+1*3+4

样例输出 

8

 

样例输入

1+1234567890*1

样例输出 

7891

样例 

样例输入

1+1000000003*1


样例输出 

4


## 提示

对于 30\%的数据,0≤ 表达式中加法运算符和乘法运算符的总数 ≤100。

对于 80\% 的数据,0≤ 表达式中加法运算符和乘法运算符的总数 ≤1000。

对于 100\% 的数据,0≤表达式中加法运算符和乘法运算符的总数 ≤100000。

思路:本题通过栈来实现。

首先读取栈的第一个数字压入栈中,然后开始循环输入,边输入边压栈;先读取字符作为计算符号,或者结束输入。 再读取整数并最多留下它的四位数; 在一次整个读取计算符号加上计算符号的后面挨着的数值后,再判断读取的计算符号是否为  ‘  X ' 号,若是,则弹出栈顶数值与当前读取的数值进行乘法运算,并将结果压入栈中;若不是,则压栈; 读取结束后,不断弹出栈顶数值进行加法运算,直到栈空。

AC代码如下:

#include<bits/stdc++.h>
using namespace std;
stack <int> st;
int main()
{
	int a,b;
	char c;
	cin>>a;
	int m=10000;
	a  = a % m;
	st.push(a);
	while(cin>>c>>b)
	{
		if(c=='*')
		{
			a=st.top();
			st.pop();
			st.push(a*b%m);
		}
		else
			st.push(b);
	}
	a = 0;
	while(st.size())
	{
		a+=st.top();
		a %= m;
		st.pop();
	}
	cout<<a<<endl;
	return 0;
}

希望大家有所收获!!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值