1.双调欧几里得旅行商问题
#include<iostream> #include<cmath> #include<cfloat> using namespace std; #define n 7 class point { public: double x,y; void set() { cin>>x>>y; } }; double dist(point p,point q) { return sqrt((p.x-q.x)*(p.x-q.x)+(p.y-q.y)*(p.y-q.y)); } void Euclidean_TSP(point p[n+1],double b[][n],int r[][n]) { b[1][2]=dist(p[1],p[2]); for(int j=3;j<=n;j++) { for(int i=1;i<j-1;i++) { b[i][j]=b[i][j-1]+dist(p[j-1],p[j]); r[i][j]=j-1; } b[j-1][j]=DBL_MAX; for(int k=1;k<j-1;k++) { double q=b[k][j-1]+dist(p[k],p[j]); if(q<b[j-1][j]) { b[j-1][j]=q; r[j-1][j]=k; } } } b[n][n]=b[n-1][n]+dist(p[n-1],p[n]); } int main() { point p[n+1]; for(int i=1;i<=n;i++)p[i].set(); double b[n][n]; int r[n][n]; Euclidean_TSP(p,b,r); cout<<b[n][n]<<endl; }
2.字符串编辑距离
Google2013校园招聘笔试题
给定一个源串和目标串,能够对源串进行如下操作:
1.在给定位置上插入一个字符
2.替换任意字符
3.删除任意字符
要求写一个程序,返回最少的操作数,使得对源串进行这些操作后等于目标串,源串和目标串的长度都小于2000。
#include<iostream> using namespace std; #define m 7 #define n 5 int min(int a,int b,int c) { int temp=(a<b)?a:b; return (temp<c)?temp:c; } void LD(char s[],char d[],int f[][n+1]) { int i,j; for(i=0;i<=m;i++)f[i][0]=i; for(j=1;j<=n;j++)f[0][j]=j; for(i=1;i<=m;i++) { for(j=1;j<=n;j++)f[i][j]=min(f[i][j-1]+1,f[i-1][j-1]+(s[i-1]==d[j-1]?0:1),f[i-1][j]+1); } } int main() { char s[m],d[n]; strcpy(s,"failing"); strcpy(d,"sailn"); int f[m+1][n+1]; LD(s,d,f); cout<<f[m][n]<<endl; return 0; }
#include<iostream> using namespace std; float max(float x,float y,float z) { x=x>y?x:y; return x>z?x:z; } float min(float x,float y,float z) { x=x<y?x:y; return x<z?x:z; } float f(float a[],int n) { float M=a[0],m=a[0],value=a[0],tmp; for(int i=1;i<n;i++) { tmp=max(a[i],M*a[i],m*a[i]); m=min(a[i],M*a[i],m*a[i]); M=tmp; if(M>value)value=M; } return value; } int main() { float a[7]={-2.5,4,0,3,0.5,8,-1}; cout<<f(a,7)<<endl; return 0; }
4.n个骰子的点数
#include<iostream> using namespace std; #define n 3 int f[n][6*n]; int g(int i,int j) { if(j>0)return f[i][j]; else return 0; } void dice() { int i,j; for(i=1;i<=6;++i)f[1][i]=1; for(i=2;i<=n;++i) { for(j=i;j<=6*i;j++)f[i][j]=g(i-1,j-1)+g(i-1,j-2)+g(i-1,j-3)+g(i-1,j-4)+g(i-1,j-5)+g(i-1,j-6); } } int main() { int i=n,s=1,a=6; while(i) { if(i&1)s*=a; i>>=1; a*=a; } dice(); for(i=n;i<=6*n;++i)cout<<f[n][i]<<' '<<(float)f[n][i]/s<<endl; return 0; }
5.12个工厂分布在一条东西向高速公路的两侧,工厂距离公路最西端的距离分别是0、4、5、10、12、18、27、30、31、38、39、47。在这12个工厂中选取3个原料供应厂,使得剩余工厂到最近的原料供应厂距离之和最短,问应该选哪三个厂?
#include<iostream> #include<cmath> using namespace std; int f[13][4]; int g(int a[],int i,int j) { int tmp=(i+j)/2,s=0; for(int k=i;k<=j;k++) { s+=abs(a[k]-a[tmp]); } return s; } int sum(int a[],int m,int n) { int i,j,k,s; for(i=1;i<=m;i++)f[i][1]=g(a,1,i); for(j=2;j<=n;j++) { for(i=j;i<=m;i++) { s=INT_MAX; for(k=j-1;k<=i-1;k++) { if(f[k][j-1]+g(a,k+1,i)<s)s=f[k][j-1]+g(a,k+1,i); } f[i][j]=s; } } return f[m][n]; } int main() { int a[13]={0,0,4,5,10,12,18,27,30,31,38,39,47}; cout<<sum(a,12,3)<<endl; return 0; }
6.Word Break(LeetCode)
#include<iostream> #include<string> #include<unordered_set> #include<vector> using namespace std; bool wordbreak(string s,unordered_set<string> dict) { vector<bool> f(s.size()+1,false); f[0]=true; for(int i=1;i<=s.size();++i) { for(int j=i-1;j>=0;--j) { if(f[j] && dict.find(s.substr(j,i-j))!=dict.end()) { f[i]=true; break; } } } return f[s.size()]; } int main() { unordered_set<string> dict; string s; while(cin>>s)dict.insert(s); cin>>s; cout<<wordbreak(s,dict)<<endl; return 0; }
7.Distinct Subsequences(LeetCode)
#include<iostream> #include<string> #include<vector> using namespace std; int DS(string S,string T) { vector<vector<int> > f(T.size()+1,vector<int>(S.size()+1)); int i,j; for(j=0;j<=S.size();++j)f[0][j]=1; for(i=1;i<=T.size();++i)f[i][0]=0; for(i=1;i<=T.size();++i) { for(j=1;j<=S.size();++j) { f[i][j]=f[i][j-1]; if(T[i-1]==S[j-1])f[i][j]+=f[i-1][j-1]; } } return f[T.size()][S.size()]; } int main() { string S="rabbbit"; string T="rabbit"; cout<<DS(S,T)<<endl; return 0; }
8.Longest Valid Parentheses
#include<iostream> #include<string> #include<vector> using namespace std; int LVP(string s) { vector<int> f(s.size(),0); int max=0; for(int i=s.size()-2;i>=0;--i) { if(s[i]=='(') { int j=i+f[i+1]+1; if(j<s.size()&&s[j]==')') { f[i]=f[i+1]+2; if(j+1<s.size())f[i]+=f[j+1]; } } if(f[i]>max)max=f[i]; } return max; } int main() { string s=")()())"; cout<<LVP(s)<<endl; return 0; }
9.有N个节点,每两个节点相邻,每个节点只与2个节点相邻,因此,N个顶点有N-1条边。每一条边上都有权值wi,定义节点i到节点i+1的边为wi。求:不相邻的权值和最大的边的集合。
int fun(int a[],int n) { int f[N]; f[0]=a[0],f[1]=max(a[0],a[1]); for(int i=2;i<n;++i) { f[i]=max(f[i-1],f[i-2]+a[i]); } return f[n-1]; }10.TSP
11.交替字符串
输入三个字符串s1、s2和s3,判断第三个字符串s3是否由前两个字符串s1和s2交错而成,且不改变s1和s2中各个字符原有的相对顺序。例如当s1 = “aabcc”,s2 = “dbbca”,s3 = “aadbbcbcac”时,则输出true;但如果s1 = “aabcc”,s2 = “dbbca”,s3=“accabdbbca”时,则输出false。