牛客练习赛95

目录

A.Duplicate Strings
简单题

#include<iostream>
#include<cstring>
#include<map>
const long long mod = 1e9 + 7;
using namespace std;
int main()
{
    long long n,q;
    long long op,k;
    map<char,long long>m;
    cin>>n>>q;
    string s;
    cin>>s;
    for(int i=0;i<n;i++){
        if(m.find(s[i])==m.end()){
            m.insert(pair<char,int>(s[i],1));
        }else{
            m[s[i]]++;
        }
    }
    while(q--){
        cin>>op;
        if(op==1){
           cin>>k;
             map<char, long long>::reverse_iterator   iter;
             for(iter = m.rbegin(); iter !=m.rend(); iter++){
                 (iter->second)+=(iter->second)*k;
                 //忘记看题目了,并且不能直接在结果中取模,考虑到空间问题?
                 //并且忘记map类型设置为long long
                 //另一解题思路,直接将字母转为数字。
                 iter->second%=mod;
             }
                  
        }else if(op==2){
            char ch;
            cin>>ch;
            cout<<m[ch]<<endl;
        }
    }
}

大写字母/小写字母及数字的ASCII码(数字)值对照:

a-z:97-122

A-Z:65-90

0-9:48-57

B.Non-interger Area

#include<iostream>
#include<cstring>
using namespace std;
int main()
{
    //计算
    //areas=0.5*(|(x3-x1)(y2-y1)-(x2-x1)(y3-y1)|)
    //if |(x3-x1)(y2-y1)-(x2-x1)(y3-y1)|为奇数则满足条件
    //思路:(x,y)有四种情况:奇偶、奇奇、偶奇、偶偶
    //     判断这些点是否满足上述式子为奇数的结果,将其点的个数相乘得到结果
    long long n;
    cin>>n;
    //***********long long类型**********
    long long a[2][2];
    memset(a,0,sizeof(a));
    for(int i=0;i<n;i++){
        long long x,y;
        cin>>x>>y;
        //统计四种类型点的数量
//         a[(x%2+2)%2][(y%2+2)%2]++;
        a[abs(x%2)][abs(y%2)]++;//奇数为1,偶数为0
        //注意加绝对值,否则出现-1
    }
    //判断四种点的组合是否符合题目要求
    long long sum=0;
    for(int x1=0;x1<2;x1++){
        for(int y1=0;y1<2;y1++){
            for(int x2=0;x2<2;x2++){
                for(int y2=0;y2<2;y2++){
                    for(int x3=0;x3<2;x3++){
                        for(int y3=0;y3<2;y3++){
                            int ans=abs((x3-x1)*(y2-y1)-(x2-x1)*(y3-y1));//注意加绝对值
                            if(ans%2==1){
                                sum+=a[x1][y1]*a[x2][y2]*a[x3][y3];
                            }
                        }
                    }
                }
            }
        }
    }
    cout<<sum/6;//除去重复部分,无序列A33=3*2*1=6

//判断
    //暴力O(n2)过不了
//     int sum=0;
//     for(int i=0;i<n-2;i++){
//         for(int j=i+1;j<n-1;j++){
//             if((a[j][1]-a[i][1])&1==1){
//                for(int j1=j+1;j1<n;j1++){
//                     if((a[j1][0]-a[i][0])&1==1){
//                         sum++;
//                     }
//                 }
//             }
//             if((a[j][0]-a[i][0])&1==1){
//                for(int j1=j+1;j1<n;j1++){
//                     if((a[j1][1]-a[i][1])&1==1){
//                         sum++;
//                     }
//                 }
//             }
//         }
//     }
//     cout<<sum<<endl;
}

叉积计算公式,S=0.5*AC *AB(向量)
求不为整数的情况个数,为整数的情况为分子等于0或偶数,则求分子为奇数情况。
暴力为O(n^{2})
将点分为四类(x,y)有四种情况:奇偶、奇奇、偶奇、偶偶
输入将点进行分类统计数量,然后通过判断四种的组合是否符合题目条件进行计算。

Division

求将区间元素全变为1 的操作,使用差分数组确定操作区间,和__lg()计算操作次数
log2(0)=-inf, __lg(0)=0;

#include<bits/stdc++.h>
#include<vector>
using namespace std;
//s为原数组,b为差分数组 
const int N=2e4+10;
long long a[N], b[N];//a存放需要操作的次数
vector<pair<int,int>> ans;
int main(){
    int n,k;
    int T;
    cin>>T;
    while(T--){
        cin>>n>>k;
        for(int i=1;i<=n;i++) {
            long long zhjian;
            cin>>zhjian;//存放原数组
            a[i]=__lg(zhjian);//O(lgn)  log2(0)=-inf
        }
        b[0]=0;
        a[0]=0;
        //构造差分数组  O(n)
        for(int i=1;i<=n;i++)b[i] = a[i]-a[i-1];
        //求差分数组元素全变为0
        ans.clear();
        int panduan=1;
        //区间修改O(1)   前加后减
        for(int l=1,r=1;l<=n;){
            while(l<=n&&!b[l]) l++;
            if(l>n) break;
            while(r<=n&&b[r]>=0) r++;
            if(l+k>r){
                cout<<-1<<endl;
                panduan=0;
                break;
            }
            ans.push_back({l,r-1});
            b[l]--,b[r]++;
        }
        if(panduan==1){
            cout<<ans.size()<<endl;
            for(auto [x,y]:ans){
                cout<<x<<" "<<y<<endl;
            }
        }

    }

    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值