NKweek-Round-106(赛时ABCDE,补F)

#单调栈 #构造 #贪心

  • 单调栈过于久远,忘了

A

题意

  • 用1*2和2*1的砖块填充3*n的矩形,判断能不能填充满

思路

  • 签到,偶数可以,奇数不行

代码

void solve(){
    int n;
    cin >> n;
    if(n%2) cout << "NO" << endl;
    else cout << "YES" << endl; 
}

B

题意

  • 给定x,最多进行k次操作,判断能不能使得操作后变为回文串
  • 记y为x翻转并去除前导0,每次操作x=x+y

思路

  • 直接模拟

代码

bool check(string s){
    for(int i=0,j=s.size()-1;i<=j;i++,j--){
        if(s[i]!=s[j]) return false;
    }
    return true;
}

long long deal(long long n){
    long long ans=0;
    while(n%10==0) n/=10;
    while(n){
        ans*=10;
        ans+=n%10;
        n/=10;
    }
    return ans;
}

void solve(){
    long long n,k;
    cin >> n >> k;
    bool ok=false;
    if(check(to_string(n))){
        cout << n << ' ' << 0 << endl;
        return ;
    }
    for(int i=1;i<=k;i++){
        n+=deal(n);
        if(check(to_string(n))){
            ok=true;
            cout << n << ' ' << i << endl;
            return ;
        }
    }
    if(!ok) cout << n << ' ' << -1 << endl;
}

C

  • 这题读题的时候发病了,从[l,r]选一个数看成了从序列的[l,r]选一个,难绷

题意

  • 给定一个序列,序列的每一位是前两位乘积的个位,给定前两个数的取值范围,和从第三位开始的n-2个数字,求解前两位,如果没有答案输出-1

思路

  • 从第三位开始只有个位,暴力枚举前两位,枚举范围最大为10
  • 要开long long

代码

void solve(){
    int n,l1,l2,r1,r2;
    cin >> n >> l1 >> r1 >> l2 >> r2;
    vector<int> a(n+10);
    for(int i=3;i<=n;i++){
        cin >> a[i];
    }
    bool ok=false;
    for(int a1=l1;a1<=min(l1+100,r1);a1++){
        for(int a2=l2;a2<=min(l2+100,r2);a2++){
            if(a1*a2%10!=a[3]||a2*a[3]%10!=a[4]) continue;
            ok=true;
            cout << a1 << ' ' << a2 << endl;
            return ;
        }
    }
    if(!ok) cout << -1 << ' ' << -1 << endl;
}

D

题意

  • 长为n的序列,你可以将任何数 变为
  • 输出将这个序列变为回文序列的最少操作数,如果无法变成,输出-1

思路

  • 显然,对一个数的操作不会改变最高位的位置,所以对应位置如果最高位不同直接寄
  • 可以证明,对于任何一个数,经过这个变换最多32次就会循环 。对于int范围的数,当 大于32,就一定会读到高位0,然后不发生变化

代码

int hibit(int x){
    int ans=0;
    while(x){
        x>>=1;
        ans++;
    }
    return ans;
}

void solve(){
    int n;
    bool ok=true;
    cin >> n;
    vector<int> a(n+10);
    vector<int> b(n+10);
    for(int i=1;i<=n;i++){
        cin >> a[i];
        b[i]=hibit(a[i]);
    }
    int ans=0;
    for(int i=1,j=n;i<=j;i++,j--){
        if(a[i]==a[j]) continue;
        if(b[i]!=b[j]){
            ok=false;
            break;
        }
        unordered_map<int,int> mi,mj;
        int cnti=0,cntj=0;
        while(mi.find(a[i])==mi.end()){
            mi[a[i]]=cnti++;
            a[i]^=(a[i]>>1);
        }
        while(mj.find(a[j])==mj.end()){
            mj[a[j]]=cntj++;
            a[j]^=(a[j]>>1);
        }
        int mn=INT_MAX;
        for(auto [x1,x2]:mi){
            for(auto [y1,y2]:mj){
                if(x1==y1) mn=min(x2+y2,mn);
            }
        }
        ans+=mn;
    }
    if(!ok) cout << -1 << endl;
    else cout << ans << endl;
}

E

题意

  • 对于一个数他的洞数值指的是:每一个数位上的数字所含的闭合空间个数
  • 给定n和sum,构造长为n,元素和不超过sum,洞数和最大的数组

思路

  • 观察到能产生贡献的只有4和8
  • 数的范围不超过1e10,每次确定一个数的一个数位,最多 的复杂度就能构造完

代码

void solve(){
    int n;
    ll sum;
    cin>>n>>sum;
    if(sum<n){
        cout<<-1<<"\n";
        return;
    }
    vector<ll>ans(n,1);
    ll rst=sum-n;
    for(int i=0;i<=9;i++){
        ll base=qpow(10,i);
        if(i==0){
            for(int j=0;j<n&&rst>=3;j++){
                ans[j]+=3;
                rst-=3;
            }
            for(int j=0;j<n&&rst>=4;j++){
                ans[j]+=4;
                rst-=4;
            }
        }else{
            ll c=4*base;
            for(int j=0;j<n&&rst>=c;j++){
                ans[j]+=c;
                rst-=c;
            }
            for(int j=0;j<n&&rst>=c;j++){
                ans[j]+=c;
                rst-=c;
            }
        }
    }
    for(int i=0;i<n;i++)cout<<ans[i]<< ' ';
    cout << endl;
}

F

题意

  • 对于一个长为n的序列,计算其满足如下要求的连续片段个数
    1. 片段长度大于等于3
    2. 片段首尾不相等
    3. 片段中所有元素需要小于片段两端元素

思路

  • 假设片段尾小于片段首,可以证明满足条件的答案至多有一个
  • 如果有第二个,则片段中间的元素(上一个)就存在大于段尾的情况,而这个唯一合法的答案其实就是左侧第一个大于当前元素的元素,所以维护一个单调递减栈,同时判断长度够不够
  • 对于另一种情况,只需要反向扫一遍序列即可

代码

#pragma GCC optimize(3)
#include<bits/stdc++.h>
#define endl '\n'
using namespace std;

int main(){
    ios::sync_with_stdio(false);
    cin.tie(0);cout.tie(0);
    
    int T;
    cin >> T;
    while(T--){
        int n;
        cin >> n;
        vector<int> a(n+10);
        for(int i=1;i<=n;i++)cin >> a[i];
        long long cnt=0;
        stack<int> st;
        for(int i=1;i<=n;i++){
            bool ok=false;
            while(!st.empty()&&a[i]>a[st.top()]) st.pop();
            if(!st.empty()&&a[st.top()]==a[i]) ok=true;
            if(!ok&&!st.empty()&&st.top()!=i-1) cnt++;
            st.push(i);
        }
        while(!st.empty()) st.pop();
        for(int i=n;i>=1;i--){
            bool ok=false;
            while(!st.empty()&&a[i]>a[st.top()]) st.pop();
            if(!st.empty()&&a[st.top()]==a[i]) ok=true;
            if(!ok&&!st.empty()&&st.top()!=i+1) cnt++;
            st.push(i);
        }        
        cout << cnt << endl;
    }
    return 0;
}
全部评论

相关推荐

emmm别问我为啥上一条帖子隔了两个月我才开始投简历和拿offer,因为我懒😰简单流程如下:周一凌晨改好的简历,然后到处乱投简历;周二接到了三维家的一面通知,临时抱佛脚的背了一些八股;周三上午一面下午通知第二天hr面;周四上午hr面下午拿offer,遂收手支线:在BOSS上顺手投了几个大厂,投字节的时候不小心投城客户端了,结果过了一天HR突然把我简历要走了,还问我能不能整客户端,我直接一口答应(脏面评警告😢)结果在周三下午的时候给我打电话,说前端有空缺实习岗,问我有没有兴趣,然后就跟我约了周四下午一面😰我都没咋准备啊,咩都不会啊😭结果周四下午面完,晚上打电话通知过一面了,赶紧把二面约在下周一下午,留点缓冲时间。逆大天了,我一半的问题都不会,他居然给我过了?运气未免有点好了😥现在正在恶补计网、网安、性能优化的东西(这三大板块我是几乎一点不会,一面几乎一点答不出来,加上我又没怎么背八股,这块被干烂了😵)心得体会与经验:1.&nbsp;我giao怎么这么快就结束了,我还以为要找好久😨2.&nbsp;大厂的面试问题真的和中厂小厂很大不同,比如在三维家我能自己吹水到vue的数据劫持、Proxy代理响应式之类的他们就觉得很不错了,但是在字节你但凡敢提到一下就会追问你细节了,一追问马脚就全漏出来了3.&nbsp;有信心真的很重要,我感觉我能拿中厂offer最重要的就是吹水吹出自信来了,以至于三维家面试反问面试官有哪里还需要改进的时候,他就说很不错了解的很多😦4.&nbsp;理解很重要,我从头到尾真没背过很多八股,不过有一些知识确实是敲过代码验证过,所以面试的时候能吹水吹得出来😇想了解面经啥的可以直接评论区问我,但我可能也说不全,因为我没有记录,而且今天摆了一天感觉记忆快清空了😵下面是故事时间:我暑假刚开始的时候才开始准备八股,印象很深那个时候连什么原型、事件循环、闭包这些名词都没听过,资料也不知道怎么找,就一直零零散散的准备,感觉也只有js稍微背了一下八股,其他很多时候都是靠完全理解和手写熟悉一些机制的,但这样做效率很低,反正准备了一个多星期半个月就开摆了😭结果一摆就摆到了开学,笔记是乱七八糟的,八股是忘光光的,简历是一直没改的,实习也是一直没投过的。直到上周日晚上偶然和师兄聊天,他突然问我“你怎么还不找实习”,那天晚上才幡然醒悟,是时候做点事情了😡然后就按照上面描述的来走了。其实我感觉我从头到尾都没背特别多八股,也没怎么找刷题资料啥的,早期就是翻尚硅谷或者黑马的入门视频从头学起,中期用面试鸭看了一点点题,主要是在学js机制和敲js代码,后期才发现了w3c的面经网站,然后在那里看着学(那个时候已经懒得敲了,因为有些问题与代码感觉不像是给找实习的看的,忒细了点😂)接下来继续准备字节二面吧,虽然几乎没啥可能可以通过,但是万一有奇迹呢?😍😍😍也祝大家能够早日拿到心仪的offer
我的offer呢😡:我已经预见10天后你会发,节孝子启动了
投递三维家等公司10个岗位
点赞 评论 收藏
分享
真tmd的恶心,1.面试开始先说我讲简历讲得不好,要怎样讲怎样讲,先讲背景,再讲技术,然后再讲提升多少多少,一顿说教。2.接着讲项目,我先把背景讲完,开始讲重点,面试官立即打断说讲一下重点,无语。3.接着聊到了项目的对比学习的正样本采样,说我正样本采样是错的,我解释了十几分钟,还是说我错的,我在上一家实习用这个方法能work,并经过市场的检验,并且是顶会论文的复现,再怎么不对也不可能是错的。4.面试官,说都没说面试结束就退出会议,把面试者晾在会议里面,丝毫不尊重面试者难受的点:1.一开始是讲得不好是欣然接受的,毕竟是学习。2.我按照面试官的要求,先讲背景,再讲技术。当我讲完背景再讲技术的时候(甚至已经开始蹦出了几个技术名词),凭什么打断我说讲重点,是不能听出人家重点开始了?这也能理解,每个人都有犯错,我也没放心上。3.我自己做过的项目,我了解得肯定比他多,他这样贬低我做过的项目,说我的工作是错误的,作为一个技术人员,我是完全不能接受的,因此我就和他解释,但无论怎么解释都说我错。凭什么,作为面试官自己不了解相关技术,别人用这个方式work,凭什么还认为这个方法是错的,不接受面试者的解释。4.这个无可厚非,作为面试官,不打招呼就退出会议,把面试者晾着,本身就是有问题。综上所述,我现在不觉得第一第二点也是我的问题,面试官有很大的问题,就是专门恶心人的,总结面试官说教,不尊重面试者,打击面试者,不接受好的面试者,技术一般的守旧固执分子。有这种人部门有这种人怎么发展啊。最后去查了一下,岗位关闭了。也有可能是招到人了来恶心人的,但是也很cs
牛客20646354...:招黑奴啊,算法工程师一天200?
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务