今日刷题
自然数的拆分
自然数的拆分问题
题目描述
任何一个大于 $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;
}
希望大家有所收获!!