腾讯音乐笔试4.18

  • 按照题意模拟即可,每两项插入0,特判null节点
   ListNode* insert0(ListNode* head) {
        ListNode* ret=head;
        while(head){
            ListNode* nxt=head->next;
            ListNode* p=new ListNode(0);
            if(nxt!=nullptr){
                head->next=p;
                p->next=nxt;
            }
            head=nxt;
        }

        return ret;
    }
  • 构造,可以知道最后一层节点有 \frac{2}{n-1},则根节点权值给\frac{2}{n-1} 往下递归时,子节点值为根节点/2即可
  void dfs(int d,TreeNode* cur,int n){
        if(d==n) return;
        cur->left=new TreeNode((cur->val)/2);
        cur->right=new TreeNode((cur->val)/2);
        dfs(d+1,cur->left,n);
        dfs(d+1,cur->right,n);
     }
    TreeNode* create(int n) {
        TreeNode* root=new TreeNode(1<<(n-1));
        dfs(1,root,n);

        return root;
    }

  • 先算出R的所有和,若为奇数,则需要在没染色的奇数格子里选奇数个方块,假设有odd个,方案数有C(odd,1)+C(odd,3)+...,偶数格子里任选,每个格子选和不选两种情况,方案数为qmi(2,even),两者相乘即可,若为偶数,则奇数方案数为C(odd,0)+C(odd,2)+...,偶数任选,两者相乘
 typedef long long ll;
     const ll N=2e5+10;
     ll a[200005],cnt=0,mod=1e9+7;
     ll fact[200005],inv[200005];
    int getMethod(ListNode* head, string colors) {
        // write code here
        ListNode* cur=head;
        while(cur){
            a[cnt++]=cur->val;
            cur=cur->next;
        }
        fact[0]=inv[0]=1;
        for(ll i=1;i<=cnt;i++){
            fact[i]=fact[i-1]*i%mod;
            inv[i]=qmi(fact[i],mod-2,mod)%mod;
        }
        ll s=0,odd=0,even=0;
        for(ll i=0;i<cnt;i++){
            if(colors[i]=='R') s+=a[i];
            else{
                odd+=(a[i]&1);
                even+=(a[i]%2==0);
            }
        }
       // cout<<s<<" "<<odd<<" "<<even<<endl;
        if(s&1){
            if(odd){
                ll ans=1,res=0;
                for(int i=1;i<=odd;i+=2){
                    res=(res+C(odd,i))%mod;
                }
                ans=res*qmi(2,even,mod)%mod;
                return ans;
            }
            else return 0;
        }else{
            cout<<s<<" "<<odd<<" "<<even<<endl;
            ll ans=1;
            ll res=0;
            for(int i=0;i<=odd;i+=2){
                res=(res+C(odd,i))%mod;
            }
            ans=res*qmi(2,even,mod)%mod;
            cout<<ans<<endl;
            return ans;
        }
    }
    ll C(ll x,ll y){
        return (((fact[x]*inv[y])%mod)*inv[x-y])%mod;
    }
    ll qmi(ll x,ll y,ll mod){
        ll res=1;
        while(y){
            if(y&1) res=res*x%mod;
            y>>=1;
            x=x*x%mod;
        }
        return res;
    }

  • 二分答案最后的最小连续1长度x是多少,问题转化为把一段连续1,转化成1连续长度不超过x,那么假设这段1长度为len,每x+1个1,就需要变1个0,分隔开他们,所以贡献值是len/(x+1),累加所有的len长度,判断贡献值和sum是否<=题目给出的最大操作数k即可
bool check(string& s,int x,int k){
        int res=0;
        for(int i=0;i<s.size();i++){
            int j=i;
            if(s[i]=='1'){
                int j=i;
                while(j+1<s.size()&&s[j+1]=='1'){
                    j++;
                }
                int len=j-i+1;
                if(len>x){
                    res+=len/(x+1);
                }
                i=j;
            }
        }
        cout<<x<<" "<<res<<" "<<k<<endl;
        return res<=k;
    }
    int maxLen(string s, int k) {
        // write code here
        int l=0,r=s.size();
        while(l<r){
            int mid=l+r>>1;
            if(check(s,mid,k)) r=mid;
            else l=mid+1;
        }

        return l;
    }

全部评论
兄弟是算法大佬啊,没必要焦虑😅
1
送花
回复
分享
发布于 04-18 22:13 广东
大佬太强了
1
送花
回复
分享
发布于 04-19 15:37 广东
秋招专场
校招火热招聘中
官网直投

相关推荐

9 18 评论
分享
牛客网
牛客企业服务