1. 数组的山谷是指数组A里面的一个连续子数组B满足:
1) B.length>=3
2) 存在i,有B[i]左边的值比它小,右边的值比它大
现给出一个数组A,找出其中的最长山谷,有就输出其长度,没有就输出为0;
输入为一个数组A; 输出为山谷的长度。
分析:
这个题只需要从左往右查找,注意边界处理即可
#include<iostream>
#include <string>
#include <vector>
using namespace std;
int main()
{
int m;
vector<int> vi;
while (cin >> m)
{
vi.push_back(m);
}
int len = vi.size();
int idown=1;
int iup=1;
int maxlen = 0, re = 0;
for (int i = 1; i < len; i++)
{
if (iup == 1)
{
if (vi[i] < vi[i - 1])
{
idown++;
}
else if (vi[i]==vi[i-1])
{
iup = 1;
idown = 1;
maxlen = 0;
}
else
{
maxlen += idown;
iup++;;
}
}
else
{
if (vi[i] > vi[i- 1])
{
iup++;;
}
else if (vi[i] == vi[i- 1])
{
maxlen += (iup-1);
if (re < maxlen)
re = maxlen;
iup = 1;
idown = 1;
maxlen = 0;
}
else
{
maxlen += (iup - 1);
if (re < maxlen)
re = maxlen;
iup = 1;
idown =2;
maxlen = 0;
}
}
}
cout << re << endl;
system("pause");
return 0;
}
2、给定一个字符串S,求出通过循环构造出S的最短字符串P;
输入:输入只包含一个用例,字符串S:abcabc
输出:最短字符串P :abc
分析:
这个题开始看到后想用最长重复子串来做,后来感觉实在不太好做,后来想想还是平移字符串的方式强行解,也即是若是循环平移k个单位,前后字符串相同,这是平移的是最短字符串。
#include<iostream>
#include <string>
#include <vector>
using namespace std;
int main()
{
string str;
cin >> str;
string s1(str);
int i = 0;
for (i = 0; i < str.size(); i++)
{
s1 += str[i];
s1.erase(s1.begin());
if (s1 == str) break;
}
if(i==str.size())
{
i = 0;
}
cout << ++i << endl;
system("pause");
return 0;
}
3、这个题是lintcode原题,题号797,到达一个数字,这里就不赘述了。
4、靓号问题
描述:手机号码0-9,一个手机号码至少有K位数相同则为靓号,若修改号码中的一个数字需要的金额为新数字与旧数字的差值(绝对值),问给出一个号码,改成靓号需要多少钱。
分析:
这个题想来想去还是只能暴力解:
1)求出替换成0-9个数为k时需要的花费,在附近像两边逐渐扩散找,比如3,可以先找4和2,找完了找3和5。
2)找出花费最小的并且替换成号码
代码如下:
#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
using namespace std;
int main()
{
int m = 0, K = 0;
cin >> m >> K;
vector<int> vi;
vector<int> vnum(10, 0);
string s;
getline(cin, s);
s.clear();
cin >> s;
for (int i = 0; i < m; i++)
{
int si = int(s[i] - '0');
vi.push_back(si);
vnum[si]++;
}
vector<vector<int>> cl(10, vector<int>(10, 0));
vector<int> mCost(10, 0);
for (int i = 0; i < 10; i++)
{
int num = K - vnum[i];
if (num <= 0) {
cl[i][i] = 0; break;
}
int flag = -1;
while (num > 0)
{
if (i + flag >= 0)
{
num = num - vnum[i + flag];
if (num <= 0) {
mCost[i] += abs(flag)*(num + vnum[i + flag]);
cl[i][i + flag] = num + vnum[i + flag]; break;
}
mCost[i] += abs(flag)*vnum[i + flag];
cl[i][i + flag] = vnum[i + flag];
}
flag = -flag;
if (i + flag < 10)
{
num = num - vnum[i + flag];
if (num <= 0) {
mCost[i] += abs(flag)*(num + vnum[i + flag]);
cl[i][i + flag] = num + vnum[i + flag]; break;
}
mCost[i] += abs(flag)*vnum[i + flag];
cl[i][i + flag] = vnum[i + flag];
}
flag = -(flag + 1);
}
}
int minCost = mCost[0], mini = 0;
for (int i = 1; i < 10; i++)
{
if (minCost > mCost[i])
{
minCost = mCost[i];
mini = i;
}
}
for (int i = 0; i < vi.size(); i++)
{
if (cl[mini][vi[i]] != 0)
{
cl[mini][vi[i]]--;
s[i] = mini + '0';
}
}
cout << minCost << endl;
cout << s << endl;
vi.clear();
vnum.clear();
mCost.clear();
cl.clear();
system("pause");
return 0;
}
这个主要还是自己记录,没有测试用例来测,只是提供一种方法,若有漏洞或好的算法欢迎大神指点。