刷题
#pragma warning(disable:4996)//屏蔽警告
//构造回文
//题目描述
//
/*
给定一个字符串s,你可以从中删除一些字符,使得剩下的串是一个回文串。如何删除才能使得回文串最长呢?
输出需要删除的字符个数。
*/
//思路
/*
其实就是,原字符串翻转之后的字符串跟原字符串的最长公共子序列
那么利用动态规划的最长公共子序列的递推关系如下
|max{ f(i,j-1) , f(i-1,j) } str[i]!=str[j]
f(i,j)= |0 i==0||j==0
|f(i-1,j-1) +1 str[i]==str[j]
时间复杂度O(n*n),
空间复杂度O(n*n)
*/
#include <algorithm>
#include <iostream>
#include <vector>
#include <string>
#include <stack>
#include <queue>
#include <string.h>
using namespace std;
unsigned int f[1001][1001];
class Solution {
public:
unsigned int plalindrome(string str) {
string revStr(str);
reverse(revStr.begin(), revStr.end());
unsigned int n = str.length();
memset(f, 0, sizeof(f));
//LCS
for (unsigned int i = 1; i <= n; i++)
{
for (unsigned int j = 1; j <= n; j++)
{
if (revStr[i-1] == str[j-1])//注意下标
f[i][j] = f[i - 1][j - 1] + 1;
else
f[i][j] = max(f[i - 1][j], f[i][j - 1]);
}
}
return n-f[n][n];
}
};
//int main()
//{
// Solution a;
// string str{"google"};
// cout << a.plalindrome(str);
// system("pause");
// return 0;
//}
int main() {
char str[1000];
Solution a;
while (scanf("%s", str) != EOF)
{
cout << a.plalindrome(str) << endl;
}
return 0;
}
#pragma warning(disable:4996)//屏蔽警告
//算法基础-字符移位
//题目描述
//
/*
小Q最近遇到了一个难题:把一个字符串的大写字母放到字符串的后面,各个字符的相对位置不变,且不能申请额外的空间。
你能帮帮小Q吗?
*/
//思路
/*
从后往前查,设两个下标指针i,j
str[i]代表需要插入的位置
str[j]代表当前正在搜索大写字母的位置
当str[j]找到大写字母,需把str[j]存起来
便让i和j之间的字母往前挪,然后str[j]替换str[i]
*/
#include <algorithm>
#include <iostream>
#include <vector>
#include <string>
#include <stack>
#include <queue>
#include <string.h>
using namespace std;
unsigned int f[1002][1002];
class Solution {
public:
string ans(string str) {
int nLen = str.length();
int i = nLen-1;
for (int j = nLen-1; j >= 0; j--)
{
if (str[j] >= 'A'&&str[j] <= 'Z')
{
char temp = str[j];
for (int k = j; k < i; k++)
str[k] = str[k + 1];
str[i] = temp;
i--;
}
}
return str;
}
};
int main() {
char str[1001];
Solution a;
while (scanf("%s", str) != EOF)
{
cout << a.ans(str) << endl;
}
return 0;
}
#pragma warning(disable:4996)//屏蔽警告
//有趣的数字
//题目描述
//
/*
小Q今天在上厕所时想到了这个问题:有n个数,两两组成二元组,差最小的有多少对呢?差最大呢?
*/
//思路
/*
*/
#include <algorithm>
#include <iostream>
#include <vector>
#include <string>
#include <stack>
#include <queue>
#include <string.h>
using namespace std;
unsigned int dat[100000];
int main() {
int n = 0;
while (scanf("%d", &n) != EOF)
{
int k = 0;
unsigned int max;
unsigned int min;
unsigned int minCount = 1, maxCount = 1;
for (int i = 0; i < n; i++)
{
scanf("%d", dat + i);
if (i == 0)
{
max = dat[0];
min = dat[0];
}
else
{
if (max == dat[i])
maxCount++;
else if (max < dat[i])
{
max = dat[i];
maxCount = 1;
}
if (min == dat[i])
minCount++;
else if (min > dat[i])
{
min = dat[i];
minCount = 1;
}
}
}
//若全部数字相同,提早退出
if (minCount == n)
{
cout << n*(n - 1) / 2 << ' ' << n*(n - 1) / 2 << endl;
continue;
}
else
maxCount = minCount*maxCount;
sort(dat, dat + n);
/*********** 求最小值的对数 ***********/
minCount = 1;
min = 0xffffffff;
int sameNum = 1;
bool isSameFlag = false;
for (int i = 1; i < n; i++)
{
unsigned int temp = dat[i] - dat[i - 1];
if(!isSameFlag)
{
if (min > temp)
{
min = temp;
minCount = 1;
}
else if (min == temp)
{
minCount++;
}
if (0 == temp)
{
isSameFlag = true;
minCount = 0;
sameNum++;
}
}
else
{
if (temp == 0)
sameNum++;
else
{
if(sameNum>1)
minCount += sameNum*(sameNum - 1) / 2;
sameNum = 1;
}
}
}
if (sameNum>1)
minCount += sameNum*(sameNum - 1) / 2;
cout << minCount << ' ' << maxCount << endl;
}
return 0;
}