【牛客竞赛】(学习记录)

//【方法熟悉】
//整数转字符串
string numberstr=to_string(number);
numberstr=numberstr.substr(0,numberstr.length()-1)
int number=stoi(numberstr)
//字符串转整数(这个我确实见的不多,一打照面跟它面面相觑,多学啊)
//【else】的妙用
给定一个长度为 n 的序列,给定一个操作,选定一个位置 i ,使得区间 [1,i] 的数据加1,区间 [i+1,n] 的数据减1,至少需要多少次操作使得这个序列不再是单调不下降子序列。
//例如1 8 10 13,操作少说明差值小,排列差值数组 
       bool decrease=true;
       //把else挪到外面,好用
        for(int i=0;i<n-1;i++)
        {
            if(a[i]>a[i+1])
        {
            decrease=false;
            break;
        }
        }
        if(!decrease)
            cout<<0<<endl;
        else
        {
            int diff[505];
             
            for(int i=0;i<n-1;i++)
            {
                diff[i]=a[i+1]-a[i];
              
            } 
            int min=*min_element(diff,diff+n-1);
            cout<<min/2+1<<endl;
            
        }
    
//【逻辑优化】
小红拿到了一个字符串,她准备将一些字母变成白色,变成白色的字母看上去就和空格一样,这样字符串就变成了一些单词。
现在小红希望,每个单词都满足以下两种情况中的一种:
1.开头第一个大写,其余为小写(长度为 1 的大写字母也是合法的)。
2.所有字符全部是小写。
小红想知道,最少需要将多少字母变成白色?
//源代码逻辑是在原数列定位最后一个大写字母位置,减去前面的几个大写字母
/*for(char c:s)
    {
        if(islower(c))
           lowerCase.push_back(c-'a');
      else
       upperCase.push_back(c-'A');
        }
    char lastCase='A'+upperCase.back();
    int lastIndex=s.find_last_of(lastCase);
    for(int i=0;i<lastIndex;i++)
    {
        if(isupper(s[i]))
            count++;
        else count=0;
    }*/
//如果是大写字母,前面是小写字母,不符合大写字母开头;如果是大写字母,不符合单独的大写字母
    //除了逻辑不够严谨还没有考虑大写字母可以单独为一组的情况
#include<bits/stdc++.h>
using namespace std;
    bool upperCase(char ch)
{
    if(ch>='A'&&ch=<'Z')
        return true;
}
bool lowerCase(char ch)
{
    if(ch>='a'&&ch=<'z')
        return true;
}
    int main()
    {
        string s;
        cin>>s;
        for(int i=0;i<s.size();i++)
        {
            if(upperCase(s[i])&&s[i-1]!=' ')
            {
            	sum++;
            	s[i]=' ';
            }
                
        }
        cout<<sum;
    }
//【逻辑优化】
//求数组的行列异或,要留出k来作为初始比对值
for(int j=0;j<m;j++)
 {
 k^=d[0][j];
 }
 for(int i=1;i<n;i++)
 {
 int data=0;
 for(int j=0;j<m;j++)
 {
 data^=d[i][j];
 }
  if(data!=k){
            cout<<"wrong answer"<<endl;
            return;
        }
    }

for(int i=0;i<m;i++)
{
    int data=0;
    for(int j=0;j<n;j++)
    {
        data^=d[j][i];
    }
     if(data!=k){
            cout<<"wrong answer"<<endl;

         return;
        }
    
}
 
大小写匹配
#include<iostream>
#include<algorithm>
#include<string>
#include<vector>
#include<unordered_map>
#define LL long long
using namespace std;

int main()
{
    LL n, k;
    cin >> n >> k;
    string s;
    cin >> s;
    vector<int> lowerCase;
    vector<int> upperCase;
    int count = 0;
    
    for (char c : s)
    {
        if (islower(c))
        {
            lowerCase.push_back(c - 'a');
        }
        else
        {
            upperCase.push_back(c - 'A');
        }
    }

    for (int i = 0; i < lowerCase.size(); i++)
    {
        for (int j = 0; j < upperCase.size(); j++)
        {
            if (lowerCase[i] == upperCase[j])
            {
                count++;
                lowerCase[i] = -1;
                upperCase[j] = -1;
                break;
            }
        }
    }

    unordered_map<int, int> charCount;
    for (int i = 0; i < lowerCase.size(); i++)
    {
        if (lowerCase[i] != -1 && k > 0)
        {
            charCount[lowerCase[i]]++;
            if (charCount[lowerCase[i]] >= 2)
            {
                k--;
                count++;
            }
        }
    }

    for (int j = 0; j < upperCase.size(); j++)
    {
        if (upperCase[j] != -1 && k > 0)
        {
            charCount[upperCase[j]]++;
            if (charCount[upperCase[j]] >= 2)
            {
                k--;
                count++;
            }
        }
    }

    cout << count;
    return 0;
}
原思路是把大小写按容器分离,根据字符转化比较两个容器的值,然后再比较两个容器自身的值是否有相同的,但是超时了(囧),所以优化了一下
for(i=0;i<n;i++){
    if(s[i]>='A'&&s[i]<='Z')
        a[s[i]-'A']++;
		if(s[i]>='a'&&s[i]<='z')
       		 b[s[i]-'a']++;
}
int count=0;
for(int i=0;i<26;i++)
{
    count+=min(a[i],b[i]);
    more+=abs(a[i]-b[i])/2;
    //同一个字母在大写字母和小写字母中出现次数之差的绝对值
}
count+=min(k,more);
平衡分组
#include <bits/stdc++.h>
using namespace std;
const int N = 310;
const int M = 200010;
const int mx = 200000;
int a[N];
int n, sum, v[M];
int main()
{
    ios :: sync_with_stdio(false);
    cin >> n;
    v[0] = 1;
    for(int i = 1; i <= n; i++)
    {
     cin >> a[i];
     sum += a[i];
    }
    int ans = mx;
    for(int i = 1;i <= n;i ++)
        for(int j = mx;j >= a[i];j --)
           if(v[j - a[i]]) v[j] = 1;
    for(int i = 1;i <= sum;i ++)
        if(v[i]) ans = min(ans,abs(sum - 2*i));
    cout<<ans;
    return 0;
}
  • 10
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值