Niuke brush questions - Tencent 2017 summer internship written test (LCS & Violence & counting)

Posted by coolphpdude on Thu, 26 Dec 2019 17:15:15 +0100

There are three questions in total. I think the first one should be considered. The remaining two are relatively simple. Just do it directly

Q1:

Solution idea: after flipping the string, find out that the longest common subsequence is the longest palindrome string. Subtract the length of the longest palindrome string from the total length is the number of characters to be deleted

The code is as follows:

#include<cstdio>
#include<stack>
#include<queue>
#include<cmath>
#include<vector>
#include<cstring>
#include<algorithm>
using namespace std;
#define CLR(a,b) memset(a,b,sizeof(a))
#define INF 0x3f3f3f3f
#define LL long long
int dp[1005][1005];
int LCS(char str[], char re[], int l)
{
	for (int i = 0 ; i <= l ; i++)
		dp[i][0] = dp[0][i] = 0;
	for (int i = 1 ; i <= l ; i++)
	{
		for (int j = 1 ; j <= l ; j++)
		{
			if (str[i-1] == re[j-1])
				dp[i][j] = dp[i-1][j-1] + 1;
			else
				dp[i][j] = max(dp[i-1][j], dp[i][j-1]);
		}
	}
	return dp[l][l];
}
int main()
{
	char str[1005];
	char re[1005];
	int l;
	while(~scanf("%s",str))
	{
		l = strlen(str);
		for (int i=0, j=l-1 ; i < l ; i++, j--)
			re[i] = str[j];
		re[l] = '\0';
		printf("%d\n",l-LCS(str,re,l));
	}
	return 0;
}

Q2:

Solution: scan it directly and move the small letters forward next to each other.

The code is as follows:

#include <cstdio>
#include <stack>
#include <queue>
#include <cmath>
#include <vector>
#include <cstring>
#include <algorithm>
using namespace std;
#define CLR(a,b) memset(a,b,sizeof(a))
#define INF 0x3f3f3f3f
#define LL long long
bool isUpper(char c)
{
	if (c >= 'A' && c <= 'Z')
		return true;
	return false;
}
int main()
{
	char str[1005];
	while(~scanf("%s",str))
	{
		int l = strlen(str);
		int cnt = 0;		//Capital letters
		for (int i = 0 ; i < l ; i++)
		{
			if (isUpper(str[i]))
				cnt++;
			else
			{
				char temp = str[i];
				for (int j=0, pos=i ; j < cnt ; j++, pos--)
					str[pos] = str[pos-1];
				str[i-cnt] = temp;
			}
		}
		printf("%s\n",str);
	}
	return 0;
}

Q3:

Solution idea: there are more situations to consider. For the first result, consider whether there are the same numbers; for the second result, consider whether all the numbers are the same.

The code is as follows:

#include <cstdio>
#include <stack>
#include <queue>
#include <cmath>
#include <vector>
#include <cstring>
#include <algorithm>
using namespace std;
#define CLR(a,b) memset(a,b,sizeof(a))
#define INF 0x7fffffff
#define LL long long
int n;
int num[100000+5];
int main()
{
	while(~scanf("%d",&n))
	{
		for (int i = 0 ; i < n ; i++)
			scanf("%d",&num[i]);
		sort(num, num+n);
		pair<int, int> ans1(INF, 0);
		pair<int, int> min_num(INF, 0);
		pair<int, int> max_num(-1, 0);
		for (int i = 0 ; i < n ; i++)
		{
			//Statistical minimum difference 
			if (i != 0)
			{
				if (num[i]-num[i-1] == ans1.first)
					ans1.second++;
				else if (num[i]-num[i-1] < ans1.first)
				{
					ans1.first = num[i]-num[i-1];
					ans1.second = 1;
				}
			}
			
			//Statistics max min
			if (num[i] == min_num.first)
				min_num.second++;
			else if (num[i] < min_num.first)
			{
				min_num.first = num[i];
				min_num.second = 1;
			}
			if (num[i] == max_num.first)
				max_num.second++;
			else if (num[i] > max_num.first)
			{
				max_num.first = num[i];
				max_num.second = 1;
			}
		}
		LL p1, p2;
		p1 = p2 = 0;
		if (ans1.first == 0)
		{
			ans1.first = num[0];
			ans1.second = 1;
			for (int i = 1 ; i < n ; i++)
			{
				if (num[i] == ans1.first)
					ans1.second++;
				else
				{
					p1 += (LL)ans1.second*(ans1.second-1)/2;
					ans1.first = num[i];
					ans1.second = 1;
				}
			}
			p1 += (LL)ans1.second*(ans1.second-1)/2;
		}
		else
			p1 = ans1.second;
		if (max_num.first == min_num.first)
			p2 = (LL)min_num.second*(min_num.second-1);
		else
			p2 = (LL)min_num.second*max_num.second;
		printf("%lld %lld\n",p1,p2);
	}
	return 0;
}