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;
}
3.最大连续乘积子串
#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。