特别注意:函数输入是否有效,例如空指针,然后引用下标时注意是否越界
可重复全排列
#include<bits/stdc++.h>
using namespace std;
void prt(char *s,int n){
int i=0;
while(s[i]=='0')i++;
for(;i<n;i++)cout<<s[i];
cout<<endl;
}
void dfs(char* s,int n,int p){//
if(p==n){
prt(s,n);
return;
}
for(char c='0';c<='9';c++){
s[p]=c;
dfs(s,n,p+1);
}
}
int main(){
int n;cin>>n;
char s[n+1];
memset(s,'0',n);
s[n]='\0';
dfs(s,n,0);
return 0;
}
不重复全排列
#include<bits/stdc++.h>
using namespace std;
void dfs(string s,int n,int p){
if(p==n)cout<<s<<endl;
for(int i=p;i<n;i++){
swap(s[p],s[i]);
dfs(s,n,p+1);
}
}
int main(){
string s;cin>>s;
dfs(s,s.size(),0);
return 0;
}
模板串匹配
#include<bits/stdc++.h>
using namespace std;
bool dfs(char* s,int i,char* t,int j){
if(s[i]=='\0'){//s到尽头了则t必须也到尽头或下一个是*
if(t[j]=='\0')return true;
if(t[j+1]='*')return dfs(s,i,t,j+2);
return false;
}
if(t[j+1]=='*'){//c对c*
if(s[i]!=t[j])return dfs(s,i,t,j+2);
return dfs(s,i+1,t,j)||dfs(s,i,t,j+2)||dfs(s,i+1,t,j+2);
}else{//c对.或c对c
if(s[i]==t[j])return dfs(s,i+1,t,j+1);
if(t[j]=='.')return dfs(s,i+1,t,j+1);
return false;
}
}
int main(){//已知t串不存在.*与**
char s[103],t[103];cin>>s;cin>>t;
if(dfs(s,0,t,0))cout<<"YES"<<endl;
else cout<<"NO"<<endl;
return 0;
}
前缀中缀求二叉树
#include<bits/stdc++.h>
using namespace std;
struct node{
char val;
struct node* lft;
struct node* rht;
}*root;
node* dfs(string s,int s1,int s2,string t,int t1,int t2){
if(s1>s2)return NULL;
node* p=new node;
p->val=s[s1];
int i;for(i=t1;i<=t2;i++)if(t[i]==s[s1])break;
p->lft=dfs(s,s1+1,s1+i-t1,t,t1,i-1);
p->rht=dfs(s,s1+i-t1+1,s2,t,i+1,t2);
return p;
}
void prt(node* p){
if(p==NULL)return ;
prt(p->lft);
prt(p->rht);
cout<<p->val;//后序遍历
}
int main(){
int n;cin>>n;
string s;cin>>s;
string t;cin>>t;
root=dfs(s,0,n-1,t,0,n-1);
prt(root);
return 0;
}
不等长数组求中位数
写法一
#include<bits/stdc++.h>
using namespace std;
int A[103],B[103];
int findkth(int A[], int m, int B[], int n, int k){
if(m > n)return findkth(B, n, A, m, k);
if(m ==0)return B[k-1];
if(k ==1)return A[0]<B[0]?A[0]:B[0];
int pa = k/2<m?k/2:m,pb = k - pa; //前k个数有pa个数在A中,有k-pa个数在B中
if(A[pa-1] < B[pb-1]) return findkth(A+pa,m-pa,B,n,k-pa); //A切去一半
if(A[pa-1] > B[pb-1]) return findkth(A,m,B+pb,n-pb,k-pb); //B切去一部分
else return A[pa-1];
}
double findMedianSortedArrays(int A[], int m, int B[], int n){
if((m+n)%2)return findkth(A,m,B,n,(m+n)/2+1);
else return ((double)findkth(A,m,B,n,(m+n)/2)+findkth(A,m,B,n,(m+n)/2+1))/2;
}
int main(){
int m,n;cin>>m>>n;
for(int i=0;i<m;i++)cin>>A[i];
for(int i=0;i<n;i++)cin>>B[i];
cout<<findMedianSortedArrays(A,m,B,n)<<endl;
return 0;
}
写法二
int find_median(int *A,int *B,int m,int n,int s,int t){
int p=(s+t)/2,c=(m+n-1)/2;/* 有多少个数小于下中位数 */
if(s>t)return find_median(B,A,n,m,0,n-1);/* 如果下中位数不在A中,就从数组B找 */
else if(A[p]>=B[c-p-1]&&A[p]<=B[c-p])return A[p];/* 数组A中有p个数小于A[p], 当且进当数组B中有c-p个数小于A[p], A[p]才是中位数 */
else if(A[p]<B[c-p-1])return find_median(A,B,m,n,p+1,t);/* A[p]太小了,从数组A中找一个更大的数尝试 */
else return find_median(A,B,m,n,s,p-1);/* A[p]太大了,从数组A中找一个更小的数尝试 */
}
int main(){
int A[]={1,3,5,7,9};
int B[]={2,4,6,8,10};
int m = sizeof(A)/sizeof(int);
int n = sizeof(B)/sizeof(int);
printf("%d\n", find_median(A, B, m, n, 0, m-1));/* 从数组A和B中找下中位数 */
return 0;
}
前中缀变后缀
#include <bits/stdc++.h>
using namespace std;
char pre[103],in[103],suf[103];
int id=0;
void vis(int s1,int s2,int t1,int t2){
if(s1>s2||t1>t2)return ;
int mid=t1;
while(pre[s1]!=in[mid])mid++;
vis(s1+1,s1+mid-t1,t1,mid-1);
vis(s1+mid-t1+1,s2,mid+1,t2);
suf[id++]=pre[s1];
}
int main(){
gets(pre);gets(in);
int len=strlen(pre);
vis(0,len-1,0,len-1);
suf[id]='\0';
cout<<suf<<endl;
return 0;
}
/*
in
1245367
4251637
out
4526731
*/