第二十组题解

A - 雷同检测

思路:简单枚举,输出时下标要加一就行了

#include
#include
#include
#include
using namespace std;
typedef long long ll;
int main()
{
	string s, ss;
	getline(cin, s);
	getline(cin, ss);
	int len1 = s.size(), len2 = ss.size();
	int len = min(len1, len2);
	for (int i = 0; i < len; i++)
		if (s[i] == ss[i])
			cout << i+1 << " ";
	return 0;
}

B - 首字母大写 

思路:我们要知道一个单词的定义是首字母前面有空格,那么我们需设置一个标记变量来记录

#include
#include
#include
using namespace std;
typedef long long ll;
int main()
{
	string s;
	getline(cin, s);
	int flag = 1;
	for (int i = 0; i

C - 大小写转换

这个没什么好说的,遍历一下字符串就行了

#include
#include
#include
using namespace std;
int main()
{
	string s;
	while (cin >> s)
	{
		for (int i = 0; i < s.size(); i++)
			if (isalpha(s[i]))
			{
				s[i] = toupper(s[i]);
				printf("%c", s[i]);
			}
			else
				printf("%c", s[i]);
		cout << endl;
	}
	return 0;
}

D - 数字反转

思路:首先判断是否为负数,我们用一个数组记录从后往前的每一位,然后遍历答案数组,去除前导0;输出即可

#include
#include
using namespace std;
int main()
{
	ll n;
	cin >> n;
	if (n < 0)
		cout << '-';
	n = abs(n);
	int a[15];
	int i = 0;
	while (n)
	{
		a[i++] = n % 10;
		n /= 10;
	}
	int flag;
	for(int j=0;j

E - 删除单词后缀

简单判断一下后三位和后两位然后输出即可

#include
#include
using namespace std;
int main(){
	char s1[100];
    gets(s1);
	int i=strlen(s1);
	if(s1[i-1]=='y'&&s1[i-2]=='l'){
 
		for(int j=0;j

F - 判断字符串是否为回文

思路:既然是回文串,从后往前读和从前往后读是一样的,那么同时从前往后和从后往前遍历一下即可,如果遇到不同的,直接return 结束;

#include
#include
using namespace std;
int main()
{
	string s;
	cin >> s;
	string str = s;
	int len = s.size();
	int t = 0;
	for(int i=len-1;i>=0;i--)
		if (s[i] != str[t++])
		{
			cout << "no";
			return 0;
		}
	cout << "yes";
	return 0;
}


G - 基础数据结构——栈(1)

第一种解法:用stack数据结构

思路:遍历字符串,如果遇到前括号并且栈为空,把它加入栈,如果栈不为空,检查该括号是否与栈顶匹配,如果匹配,栈顶的括号出栈,否则该括号入栈,最后检查栈是否为空,如果为空,说明括号全部匹配。

#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
typedef long long ll;
stacks;
char trans(char a)
{
	if (a == ')')return '(';
	if (a == '}')return '{';
	if (a == ']')return '[';
	return '\0';
}
bool check(char c)
{
	if (c == '(' || c == ')' || c == '[' || c == ']' || c == '{' || c == '}')
		return false;
	return true;
}
int main()
{
	string str;
	while (getline(cin,str))
	{
		while (!s.empty())s.pop();
		for (int i = 0; i < str.size(); i++)
		{
			if (check(str[i]))continue;
			if (s.empty())
			{
				s.push(str[i]);
				continue;
			}
			if (trans(str[i]) == s.top())
				s.pop();
			else
				s.push(str[i]);

		}
		if (s.empty())puts("yes");
		else puts("no");
	}
	return 0;
}

第二种解法

和栈一样的思路,只不过换成数组实现

#include 
#include 
#include 
#define N 1001
int main()
{
    char s[N], a[N];
    while(gets(s))
    {
        int len,i,top = 0;
        len= strlen(s);
        for(i = 0; i < len; i++)
        {
            if(s[i] == '(' || s[i] == '[' || s[i] == '{')
                a[++top] = s[i];
            else if(s[i] == ')')
            {
                if(a[top] == '(')   top--;
                else
                {
                    top++;
                    break;
                }
            }
            else if(s[i] == ']')
            {
                if(a[top] == '[')   top--;
                else
                {
                    top++;
                    break;
                }
            }
            else if(s[i] == '}')
            {
                if(a[top] == '{')  top--;
                else
                {
                    top++;
                    break;
                }
            }
        }
        if(top!=0)  printf("no\n");
        else   printf("yes\n");
    }
    return 0;
}


H - 字典序

用c++string类,重载<,直接比较即可

#include
#include 
using namespace std;
int main()
{
    string a, b;
    cin >> a >> b;
    if(a < b) cout << "YES";
    else  cout << "NO";
    return 0;
}

思路:

I - 验证子串

第一种解法:用string类的find函数

使用方法:如在string1中查找string2,string1.find(string2);返回值为string2第一次在string1中出现的位置。
若希望在特定位置开始查找,可使用 string1.find(string2,location);
如果找不到,则返回值为string::npos ,即对于string,通过a.find(val)==string::npos来做判断是否查找成功

#include 
#include 
using namespace std;
string a, b;
int main(){
    cin >> a >> b;
    if (a.find(b) != string::npos)
        cout << b << " is substring of " << a;
    else if (b.find(a) != string::npos)
        cout << a << " is substring of " << b;
    else
        cout << "No substring";
   
    return 0;
}

第二种解法:



J - 子串查找

第一种解法:哈希表

思路:嗯。。差不多也是模板,按套路先进行两个字符串的预处理,然后要查找子串的话,就等价于在主串中查找一段长度与子串一样的而且子串哈希值相同的一段字符,那我们预处理之后正常枚举在主串中的起点即可,记录答案输出

#include
#include
#include
#include
using namespace std;
typedef long long ll;
const ll mod = 1e9+7;
const int base = 29;
ll hase1[1000005], hase2[1000005];
ll pre1[1000005], pre2[1000005];
int main()
{
	pre1[0] = pre2[0] = 1;
	string s, str;
	cin >> s >> str;
	int len1 = s.size(), len2 = str.size();
	for (int i = 0; i < len1; i++)
		hase1[i + 1] = (hase1[i] * base + (s[i] - 'a' + 1)) % mod;
	for (int i = 1; i < len1; i++)
		pre1[i] = pre1[i - 1] * base % mod;
	for (int i = 0; i < len2; i++)
		hase2[i + 1] = (hase2[i] * base + (str[i] - 'a' + 1)) % mod;
	for (int i = 1; i < len2; i++)
		pre2[i] = pre2[i - 1] * base % mod;
	int ans = 0;
	for (int i = 0; i + len2  <= len1; i++)
	{
		ll res = ((hase1[i + len2] - hase1[i] * pre1[len2]) % mod + mod) % mod;
		if (res == hase2[len2])
			ans++;
	}
	cout << ans;
	return 0;
}

第二种解法:kmp

kmp的模板,说实话直接无脑套就可以了。

#include 
#include 
#define inf 1000000007
#define wc 1e-8
using namespace std;
typedef long long ll;
string s,p;
int a[1000010];
void xx(string p){
    a[0]=-1;
    int i=0,j=-1,l=p.size();
    while(i>s;
    cin>>p;
    cout<

L - 最长回文子串

第一种解法:动态规划思想

我们用 P(i,j) 表示字符串 s 的第 ii到 j个字母组成的串是否为回文串:

动态规划方程:如果p[i+1][j-1]是回文子串并且s[i]==s[j],p[i][j]才会是回文子串


#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
typedef long long ll;

int main()
{
	string s;
	cin >> s;
    int len = s.size();
    if (len < 2)
    {
        cout << s;
        return 0;
    }
    vector< vector > dp(len, vector(len));
    //先初始化
    for (int i = 0; i < len; i++)
        dp[i][i] = true;
    int l, r;
    l = r = 0;
    for (int L = 2; L <= len; L++)
    {
        for (int i = 0; i < len; i++)
        {
            int j = L + i - 1;//右边界
            if (j >= len)  break;
            if (s[i] != s[j])
                dp[i][j] = false;
            else
            {
                if (j - i < 3)
                    dp[i][j] = true;
                else {
                    dp[i][j] = dp[i + 1][j - 1];
                }
            }
            if (dp[i][j] && j - i > r - l)
            {
                l = i, r = j;
            }
        }
    }
    cout << r - l + 1;
	return 0;
}

第二种解法:中心扩散法

思路:对于回文子串,我们考虑枚举每个子串的中心点,向两边扩散,字串长度有奇有偶,所以我们一共要枚举2*n-1个中心点,然后每次更新长度最长的子串,记录答案

                                                                c++版本

#include
#include
using namespace std;
typedef long long ll;
int reverse_my(string str, int left, int right)
{
	//以left和right为中心扩散
	int l = left, r = right;
	while (l >= 0 && r < str.size() && str[l] == str[r])
		r++, l--;
	return r - l - 1;
}
int main()
{
	string s;
	cin >> s;
	int len = s.size();
	int res = 0;
	int begin, end;
	for (int i = 0; i < len; i++)
	{
		int res1 = reverse_my(s, i, i);
		int res2 = reverse_my(s, i, i + 1);
		res = max(max(res1, res2), res);
	}
	cout << res;
	return 0;
}

                                                 c语言版本

#include
#include
int main()
{
	char s[1000];
	int i,l,max,j,k,x,y;
	scanf("%s",s);
	int a[1000]={1},b[1000]={0};
	l=strlen(s);
	for(i=0;i=0&&k=0&&k

你可能感兴趣的:(蓝桥杯,c++,职场和发展)