1、逆波兰表达式
(1)题目描述

逆波兰表达式是一种把运算符前置的算术表达式,例如普通的表达式2 + 3的逆波兰表示法为+ 2 3。逆波兰表达式的优点是运算符之间不必有优先级关系,也不必用括号改变运算次序,例如(2 + 3) * 4的逆波兰表示法为* + 2 3 4。本题求解逆波兰表达式的值,其中运算符包括+ - * /四个。

【输入】 输入为一行,其中运算符和运算数之间都用空格分隔,运算数是浮点数。

【输出】 输出为一行,表达式的值。

可直接用printf("%f\n", v)输出表达式的值v。

【输入样例】

* + 11.0 12.0 + 24.0 35.0

【输出样例】 1357.000000

(2)AC代码

使用char类型的数组存储字符串,就可以使用 atof()函数将字符串转换为浮点数

#include<iostream>
#include<set>
#include<vector>
#include<cmath>
#include<algorithm>
#include<map>
#include<string>
#include<cstring>
using namespace std;

char str[105];
double res;
double fun()
{
	scanf("%s",str);
	switch(str[0])
	{
		case '+':
			res= fun()+fun();
			break;
		case '-':
			res= fun()-fun();
			break;
		case '*':
			res= fun()*fun();
			break;
		case '/':
			res= fun()/fun();
			break;
		default:
			res= atof(str);
	}
	return res;
}
int main()
{
	printf("%f\n",fun());
	
    return 0;
}
2、全排列
(1)题目描述

给定一个由不同的小写字母组成的字符串,输出这个字符串的所有全排列。

我们假设对于小写字母有‘a’ <‘b’ < ... <‘y’<‘z’,而且给定的字符串中的字母已经按照从小到大的顺序排列。

【输入】 只有一行,是一个由不同的小写字母组成的字符串,已知字符串的长度在1到6之间。

【输出】 输出这个字符串的所有排列方式,每行一个排列。要求字母序比较小的排列在前面。字母序如下定义:

已知S=s1s2...sk,T=t1t2...tk ,则S<T等价于,存在p(1<=p<=k),使得s1=t1,s2=t2,...,sp−1=tp−1,sp<tp 成立。

【输入样例】 abc 【输出样例】 abc acb bac bca cab cba

(2)AC代码

直接使用STL的内置函数:next_permutation(),生成全排列

#include<iostream>
#include<set>
#include<vector>
#include<cmath>
#include<algorithm>
#include<map>
#include<string>
#include<cstring>
using namespace std;
typedef long long ll;
const int N=100005;


int main()
{
	ios::sync_with_stdio(false);
	cin.tie(0);
	cin.tie(0);
	
	string s;
	getline(cin,s);
	
	do{
		cout<<s<<endl;
	}while(next_permutation(s.begin(),s.end()));
	
    return 0;
}

使用dfs搜索

#include<iostream>
#include<string>
#include<cstring>
using namespace std;

string s;
bool vis[7];
void dfs(int index,int len,string res)
{
	if(index==len)
	{
		cout<<res<<endl;
		return;
	}
	for(int i=0;i<len;i++)
	{
		if(!vis[i])
		{
			vis[i]=true;
			dfs(index+1,len,res+s[i]);
			vis[i]=false;
		}
	}
}
int main()
{
	ios::sync_with_stdio(false);
	cin.tie(0);
	cin.tie(0);
	
	
	getline(cin,s);
	int len= s.length();
	dfs(0,len,"");
	
    return 0;
}
3、最大公约数
(1)题目描述

给定两个正整数,求它们的最大公约数。

【输入】 输入一行,包含两个正整数(<1,000,000,000)。

【输出】 输出一个正整数,即这两个正整数的最大公约数。

【输入样例】 6 9 【输出样例】 3

(2)AC代码

使用 long long 没有必要,但是本人有这个习惯。。

#include<iostream>
#include<string>
#include<cstring>
using namespace std;
typedef long long ll;

ll a,b;
ll fun(ll x,ll y)
{
	if(y==0)return x;
	else return fun(y,x%y);
}
int main()
{
	ios::sync_with_stdio(false);
	cin.tie(0);
	cin.tie(0);
	
	
	cin>>a>>b;
	cout<<fun(a,b);
	
    return 0;
}
4、因子分解
(1)题目描述

输入一个数,输出其素因子分解表达式。

【输入】 输入一个整数 n (2≤n<100)。

【输出】 输出该整数的因子分解表达式。

表达式中各个素数从小到大排列。

如果该整数可以分解出因子a的b次方,当b大于1时,写做 a^b ;当b等于1时,则直接写成a。 【输入样例】 60 【输出样例】 2^235

(2)AC代码

方法一,使用vector+数组,但是适用于n的范围确定且n较小的情况,本题可以通过。

#include<iostream>
#include<cmath>
#include<algorithm>
#include<vector>
using namespace std;
vector<int>v;
int a[100]={0};
// 判断素数
bool prime(int n)
{
	int t=(int)sqrt(n);
	if(n==1)return false;
	if(n==2||n==3)return true;
	for(int i=2;i<=t;i++)
	{
		if(n%i==0)return false;
	}
	return true;
}
// 分解
void fun(int n)
{
	int t=(int)sqrt(n); // 只需要枚举到根号n
	for(int i=2;i<=t;i++)
	{
		if(n%i==0)
		{
			if(prime(i))
			{
				v.push_back(i); // 是素数就加入
			}
			if(prime(n/i))
			{
				v.push_back(n/i);// 判断另一个是不是素数
			}else
			{
				fun(n/i);// 另一个不是素数,递归判断 n/i
				break;// 要终止此次n的判断
			}
		}
	}
}
int main()
{
	int n;
	cin>>n;
	fun(n);
	sort(v.begin(),v.end());
	
	for(unsigned i=0;i<v.size();i++)
	{
		a[v[i]]++;// 求每个因数的个数,利用桶排序思想
	}
	bool flag=true;
	for(int i=0;i<100;i++)
	{
		if(a[i]!=0)
		{
			if(!flag)cout<<"*";// 第一个输出前不加 *
			if(a[i]>1)
			{
				cout<<i<<"^"<<a[i];
				flag=false;
			}else
			{
				cout<<i;
				flag=false;
			}
		}
	}
	return 0;
}

方法二,使用STL的map,直接统计,且不受n的大小制约

#include<iostream>
#include<set>
#include<vector>
#include<cmath>
#include<algorithm>
#include<map>
#include<string>
#include<cstring>
using namespace std;

int n;
map<int,int> m;
bool prime(int x)
{
	if(x==1||x==0)return false;
	if(x==2||x==3)return true;
	int t=(int)sqrt(x);
	for(int i=2;i<=t;i++)
	{
		if(x%i ==0)return false;
	}
	return true;
}
void fun(int x)
{
	int t=(int)sqrt(x);// 必须是根号x,不能是x/2,否则会重复判断
	for(int i=2;i<=t;i++)
	{
		if(x%i==0)
		{
			if(prime(i))
			{
				m[i]++;	
			}
			if(prime(x/i))
				m[x/i]++;
			else{
				fun(x/i);
				break;
			}
		}
	}
}
int main()
{
	ios::sync_with_stdio(false);
	cin.tie(0);
	cin.tie(0);
	
	
	cin>>n;
	if(prime(n))
	{
		cout<<n;
		return 0;
	}
	fun(n);
	map<int,int>::iterator it=m.begin();
	if(it->second > 1)
	{
		cout<<it->first<<"^"<<it->second;
	}else{
		cout<<it->first;
	}
	it++;
	for(;it!=m.end();it++)
	{
		if(it->second > 1)
		{
			cout<<"*"<<it->first<<"^"<<it->second;
		}else{
			cout<<"*"<<it->first;
		}
	}
    return 0;
}