[Algorithm][综合训练][非对称之美][添加字符][数组变换]详细讲解


1.非对称之美

1.题目链接


2.算法原理详解 && 代码实现

  • 自己的版本:动态规划 --> 内存超限 --> 23.44%
    #include <iostream>
    #include <string>
    #include <vector>
    using namespace std;
    
    int main()
    {
        string str;
        cin >> str;
    
        int n = str.size();
        vector<vector<bool>> dp(n, vector<bool>(n, false));
    
        int maxLen = 0;
        for(int i = n - 1; i >= 0; i--)
        {
            for(int j = i; j < n; j++)
            {
                if(str[i] == str[j])
                {
                    dp[i][j] = i + 1 < j ? dp[i + 1][j - 1] : true;
                }
                
                if(!dp[i][j])
                {
                    maxLen = max(maxLen, j - i + 1);
                }
            }
        }
    
        cout << maxLen << endl;
    
        return 0;
    }
    
  • 优化版本:规律 + 贪心
    #include <iostream>
    #include <string>
    using namespace std;
    
    int n;
    string str;
    
    int Adjust()
    {
    	// 1.判断是否全都是相同字符
    	bool flag = true;
    	for(int i = 1; i < n; i++)
    	{
    		if(str[i] != str[0])
    		{
    			flag = false;
    			break;
    		}
    	}
    
    	if(flag)
    	{
    		return 0;
    	}
    
    	// 2.判断本身是否是回文
    	flag = true;
    	int left = 0, right = n - 1;
    	while(left < right)
    	{
    		if(str[left] == str[right])
    		{
    			left++;
    			right--;
    		}
    		else
    		{
    			flag = false;
    			break;
    		}
    	}
    
    	if(flag)
    	{
    		return n - 1;
    	}
    	else
    	{
    		return n;
    	}
    }
    
    int main()
    {
    	cin >> str;
    	n = str.size();
    
    	cout << Adjust() << endl;
    
    	return 0;
    }
    

2.添加字符

1.题目链接


2.算法原理详解 && 代码实现

  • 解法:暴力枚举
    #include <iostream>
    #include <string>
    using namespace std;
    
    int main()
    {
    	string a, b;
    	cin >> a >> b;
    	int m = a.size(), n = b.size();
    
    	int ret = m;
    	for(int i = 0; i <= n - m; i++) // 枚举b的起始位置
    	{
    		int tmp = 0;
    		for(int j = 0; j < m; j++)
    		{
    			if(a[j] != b[i + j])
    			{
    				tmp++;
    			}
    		}
    
    		ret = min(tmp, ret);
    	}
    
    	cout << ret << endl;
    	
    	return 0;
    }
    

3.数组变换

1.题目链接


2.算法原理详解 && 代码实现

  • 自己的版本:排序 + 模拟 --> 100%
    #include <iostream>
    #include <algorithm>
    #include <vector>
    using namespace std;
    
    bool Check(int small, int large)
    {
        while(small < large)
        {
            if((small *= 2) == large)
            {
                return true;
            }
        }
    
        return false;
    }
    
    int main()
    {
        int n = 0;
        cin >> n;
    
        vector<int> nums(n, 0);
        for(int i = 0; i < n; i++)
        {
            cin >> nums[i];
        }
    
        sort(nums.begin(), nums.end());
    
        int r = n - 1;
        while(r > 0)
        {
            if(Check(nums[r - 1], nums[r]) || nums[r] == nums[r - 1])
            {
                r--;
            }
            else
            {
                break;
            }
        }
    
        cout << (r == 0 ? "YES" : "NO") << endl;
    
        return 0;
    }
    
  • 优化版本:贪心 + 位运算
    • 贪心:以最大值为基准,判断较小的数都否变成最大值
    • 位运算:判断一个数是否是x 2 n 2^n 2n
      • 方法一x - (x & -x) == 0 ? true : false
        • x & -x提取出最后一个二进制为1的位
        • 如果该位为仅有的二进制位为1的位,则是
      • 方法二x & (x - 1) == 0 ? true : false
    #include <iostream>
    #include <vector>
    using namespace std;
    
    int n = 0, maxValue = 0;
    vector<int> nums;
    
    bool Check()
    {
    	for(int i = 0; i < n; i++)
    	{
    		if(maxValue % nums[i])
    		{
    			return false;
    		}
    
    		int x = maxValue / nums[i];
    		if(x - (x & -x))
    		{
    			return false;
    		}
    	}
    
    	return true;
    }
    
    int main()
    {
    	
    	cin >> n;
    	nums.resize(n, 0);
    	
    	for(auto& x : nums)
    	{
    		cin >> x;
    		maxValue = max(x, maxValue);
    	}
    
    	if(Check())
    	{
    		cout << "YES" << endl;
    	}
    	else
    	{
    		cout << "NO" << endl;
    	}
    
    	return 0;
    }
    
评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

DieSnowK

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值