title: C++奥赛一本通刷题记录(递归)
date: 2017-11-09
tags:
- 一本通
- openjudege
categories: OI
C++奥赛一本通刷题记录(递归)
2017.11.9 By gwj1139177410
- 逆波兰表达式 openjudge1696
//栈比较坑。。。
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<math.h>
char a[3010];
double trans(){ //float is bugs
scanf("%s",a);
if(strlen(a)==1){
if(a[0]=='+')return trans()+trans();
if(a[0]=='-')return trans()-trans();
if(a[0]=='*')return trans()*trans();
if(a[0]=='/')return trans()/trans();
}else{
return atof(a);
}
}
int main(){
printf("%f\n", trans());
return 0;
}
- 全排列 openjudge1750
//直接套模板,据说STL也能水
#include<cstdio>
#include<cstring>
const int maxn = 110;
char a[maxn], b[maxn];
int n, vis[maxn];
void dfs(int cur){
if(cur == n){
for(int i = 0; i < n; i++)putchar(b[i]);
printf("\n");
}else for(int i = 0; i < n; i++){
if(!vis[i]){
vis[i] = 1;
b[cur] = a[i];
dfs(cur+1);
vis[i] = 0;
}
}
}
int main(){
scanf("%s", a); n = strlen(a);
dfs(0);
return 0;
}
- 分解因数 openjudge1751
//这题我第一个想法是排列组合,数论,然后。。。。
#include<iostream>
using namespace std;
int f(int n, int m){ //找n的分解方案数
if(n == 1)return 0;
int ans = 1; //加上题目自己算一个值
for(int i = m; i*i <= n; i++)//枚举n的每个约数,每次除掉(从小到大去重)
if(n%i==0)ans += f(n/i,i);
return ans;
}
int main(){
int T; cin>>T;
while(T--){
int n; cin>>n;
cout<<f(n,2)<<"\n";//找约数从2开始
}
return 0;
}
- 斐波那契数列 openjudge1755
//╮( ̄▽ ̄)╭数据太水我也没办法
#include<iostream>
using namespace std;
int f(int n){
return n==1||n==2?1:f(n-1)+f(n-2);
}
int main(){
int T; cin>>T;
while(T--){
int n; cin>>n;
cout<<f(n)<<"\n";
}
return 0;
}
- pell数列 openjudge1788
//(⁄ ⁄•⁄ω⁄•⁄ ⁄)这个没有记忆化药丸了
#include<iostream>
using namespace std;
int f[1000010];
int fn(int n){
return f[n]?f[n]:f[n]=(2*fn(n-1)+fn(n-2))%32767;
}
int main(){
f[1]=1; f[2]=2;
int T; cin>>T;
while(T--){
int n; cin>>n;
cout<<fn(n)<<"\n";
}
return 0;
}
- 括号匹配问题 openjudge2705
//模拟题一番水
#include<iostream>
#include<string>
#include<stack>
using namespace std;
int main(){
string s, t;
stack<int>sk, tk;
while(getline(cin,s)){
t.resize(s.size());
for(int i = 0; i < s.size(); i++){
t[i] = ' ';
if(s[i]=='(')sk.push(i);
if(s[i]==')'){
if(sk.size())sk.pop();
else tk.push(i);
}
}
while(sk.size()){
t[sk.top()] = '$';
sk.pop();
}
while(tk.size()){
t[tk.top()] = '?';
tk.pop();
}
cout<<s<<"\n"<<t<<"\n";
}
return 0;
}
- 爬楼梯 openjudge3089
#include<iostream>
using namespace std;
int a[50];
int f(int n){
return a[n]?a[n]:a[n]=f(n-1)+f(n-2);
}
int main(){
a[1]=1; a[2]=2; //稍微注意一下边界就好啦
int n;
while(cin>>n){
cout<<f(n)<<"\n";
}
return 0;
}
- 汉诺塔问题 openjudge6261
//这种就是经常出现在初赛看程序写结果里面的
//ha2():将n个盘子从a经过c移动到b
#include<iostream>
using namespace std;
void ha2(int n, char a, char b, char c){
if(!n)return ;
ha2(n-1,a,c,b); //把前n-1个盘子移动到辅助的杆c
cout<<a<<"->"<<n<<"->"<<b<<"\n";//然后把自己移动到目标杆b
ha2(n-1,c,b,a);//最后再把前n-1个盘子通过辅助的杆a辅助移动到目标杆b
}
int main(){
int n; char a, b, c;
cin>>n>>a>>b>>c;
ha2(n,a,b,c);
return 0;
}
- 放苹果 openjudge666
//已经很水啦,貌似递推做过呢
#include<iostream>
using namespace std;
int f(int m, int n){
if(m==0 || n==1)return 1;
return n>m?f(m,m):f(m,n-1)+f(m-n,n);
}
int main(){
int T; cin>>T;
while(T--){
int m, n; cin>>m>>n;
cout<<f(m,n)<<"\n";
}
return 0;
}
- 求最大公约数问题 openjudge7592
#include<iostream>
using namespace std;
typedef long long LL;
LL gcd(LL a, LL b){
return !b?a:gcd(b,a%b);
}
int main(){
LL a, b; cin>>a>>b;
cout<<gcd(a,b)<<"\n";
return 0;
}
- 2的幂次方表示 openjudge8758
//直接模拟就好啦
#include<iostream>
using namespace std;
void dfs(int dep, int n){
//if(n<=2){ cout<<n; return; }
int flag = 0;
for(int i = dep; i >= 0; i--){
if(n&(1<<i)){
if(flag)cout<<"+";
if(i == 1)cout<<2;
else if(i==0||i==2)cout<<"2("<<i<<")";//等价于边界条件
else{
cout<<"2(";
dfs(dep,i);
cout<<")";
}
flag = 1;
}
}
}
int main(){
int n; cin>>n; dfs(30,n);
return 0;
}
- 分数求和 openjudge12
//gcd&lcm
#include<iostream>
using namespace std;
int gcd(int a, int b){
return !b?a:gcd(b,a%b);
}
int lcm(int a, int b){
return a/gcd(a,b)*b;
}
int main(){
int a=0, b=1;
int T; cin>>T;
while(T--){
int c, d; cin>>c; cin.get(); cin>>d;
int t = lcm(b,d);
a = a*(t/b)+c*(t/d); b = t;
while((t=gcd(a,b))!=1){
a/=t; b/=t;
}
}
if(b==1||a==0)cout<<a<<"\n";
else cout<<a<<"/"<<b<<"\n";
return 0;
}
- 因子分解 openjudge22
#include<iostream>
using namespace std;
int main(){
int n, flag=0; cin>>n;
for(int i = 2; i <= n; i++){
int cnt = 0;
while(n%i==0){
n /= i; cnt++;
}
if(cnt){
if(flag)cout<<"*";
if(cnt==1)cout<<i;
else cout<<i<<"^"<<cnt;
flag = 1;
}
}
return 0;
}
- 判断元素是否存在 openjudge41
//感觉有点绕,拿set水了
#include<iostream>
#include<set>
using namespace std;
set<int>s;
int main(){
int k, x, t; cin>>k; cin.get(); cin>>x;
s.insert(k); t = k; int cnt = 0;
for(set<int>::iterator it = s.begin(); it!=s.end(); it++){
s.insert(2*(*it)+1); s.insert(3*(*it)+1);
if(*(--s.end())>x)cnt++;
if(cnt>1000)break;//强行搞事情
}
if(s.count(x))cout<<"YES\n";else cout<<"NO\n";
return 0;
}
//开个玩笑的,不过这也算递归?
#include<iostream>
using namespace std;
const int maxn = 300010;
int a[maxn];
void enlarge(int x){
if(x<maxn){
a[x] = 1;
enlarge(2*x+1);
enlarge(3*x+1);
}else return ;
}
int main(){
int k, x; cin>>k; cin.get(); cin>>x;
enlarge(k);
if(a[x])cout<<"YES\n";else cout<<"NO\n";
return 0;
}