250pt
题意:
给定一个字符串,求没有重复字符的最长子串。
分析:
直接暴力枚举所有子串(开始位置和结束位置)。
View Code
class ChocolateBar
{
public:
int maxLength(string s)
{
int i,j,k,t,ii,flag,a[28],n=s.size();
for(i=k=0;i<n;i++)
for(j=i;j<n;j++)
{
memset(a,0,sizeof(a));
t=0;
flag=1;
for(ii=i;ii<=j;ii++)
a[s[ii]-'a']++;
for(ii=0;ii<28;ii++)
if(a[ii])
{
t++;
if(a[ii]>1)
flag=0;
}
if(flag&&t>k)
k=t;
}
return k;
}
};
500pt:
题意:
旅行商问题的变种。
给定顶点不超过50个的图和它们之间的边,每个顶点都有一个权值(0<=v<1024),一个旅行商一开始在第0个点,权值为v[0],只要右边,可以任意访问任何顶点,每到一个,已获得的权值更新异或该点权值,求在此过程中,权值的最大值。
分析:
广搜。因为权值的范围很小,所以可用顶点和权值表示状态。用dp[i,j]的值表示能否在第i个顶点达到权值j。
PS.没注意到权值的范围很小,以为要深搜加剪枝,遇到搜索就发憷,一看别人代码就知道怎么写了。读题还是不够仔细。
View Code
class XorTravelingSalesman
{
public:
bool dp[51][1024];
int maxProfit(vector <int> v, vector <string> r)
{
int i,j,k,ret,n=v.size();
ret=v[0];
memset(dp,false,sizeof(dp));
queue<pair<int ,int> > q;
q.push(make_pair(0,v[0]));
dp[0][v[0]]=true;
while(!q.empty())
{
i=q.front().first;
k=q.front().second;
q.pop();
for(j=0;j<n;j++)
if(r[i][j]=='Y'&&!dp[j][k^v[j]])
{
dp[j][k^v[j]]=true;
if((k^v[j])>ret)
ret=(k^v[j]);
q.push(make_pair(j,k^v[j]));
}
}
return ret;
}
};
1000pt:
题意:
给定一个数列,从左到右依次取数,取出组成一个新数列,取出的数可以放到新数列的左边或右边,求使开头第一个数不为0,字典序最小的新数列。
分析:
一开始想贪心,取出的数只要和新数列的最左边数比较,小或等则放左,大则放右。
因为前导0的干扰,此法不可行。后来转到动态规划,发现状态不好表示。又转回贪心,只要事先去掉前导0的干扰就完全可行,即先找到新数列的最左边的数(从旧数列右往左找最小数),最小数之后的数全放有侧,之前的数按照前法贪心。
PS.这题很可惜,因为不熟悉vector的insert而来不及在比赛的时候提交。虽然我后来交的时候也不能肯定算法一定是对的。
View Code
class LeftRightDigitsGame
{
public:
string minNumber(string s)
{
int i,j,k,l,a[55],n=s.size();
string ret;
memset(a,0,sizeof(a));
for(j=n-1;s[j]=='0';j--);
for(i=n-1;i>=0;i--)
if(s[i]!='0'&&s[i]<s[j])
j=i;
for(k=n-1;k>j;k--)
a[k]=1;
a[k]=0;
l=s[0]-'0';
for(i=1;i<k;i++)
if(s[i]-'0'<=l)
l=s[i]-'0',a[i]=0;
else
a[i]=1;
ret.push_back(s[0]);
for(i=1;i<n;i++)
if(a[i])
ret.push_back(s[i]);
else
ret.insert(ret.begin(),s[i]);
return ret;
}
};
转载于:https://www.cnblogs.com/xchaos/archive/2012/09/17/2688160.html