阿里实习生2021-3-15场笔试题

第一题:翻转数字

给你三个数a,b,c,可以对a或b进行多次翻转,[一次翻转的意思是取一位二进制进行翻转(比如0->1,或者1->0)],现在问你最少需要多少次翻转可以使得翻转后的a|b=c。


这里给一下我的代码吧~
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.PrintWriter;
import java.util.Scanner;

/**
 *
 * @author Soarkey
 * @date 2021/3/15
 */
public class Main {
    public static void main(String[] args) {
        Scanner in = new Scanner(new BufferedInputStream(System.in));
        PrintWriter out = new PrintWriter(new BufferedOutputStream(System.out));

        int t = in.nextInt();
        while (t-- != 0) {
            int a = in.nextInt();
            int b = in.nextInt();
            int c = in.nextInt();

            int ans = 0;
            // 获取二进制位
            while (a != 0 || b != 0 || c != 0) {
                int i = a & 1;
                int j = b & 1;
                int k = c & 1;
                if ((i | j) != k) {
                    if (k == 1) {
                        ++ans;
                    } else { // k == 0
                        if ((i & j) == 1) {
                            ans += 2;
                        } else {
                            ++ans;
                        }
                    }
                }

                a >>= 1;
                b >>= 1;
                c >>= 1;
            }
            out.println(ans);
        }

        in.close();
        out.close();
    }
}

第二题:蜡烛

现在有一根蜡烛长 n 厘米,从一端点火,然后对n-1个位置进行随机切割,将蜡烛分为两段,x和n-x,待较短的一段燃尽后(这里假设x段比较短,较短的一段燃尽后,两段蜡烛长度就变成了 0 和 n-x-x 了,注意这里两段蜡烛是同时在燃烧!!),再对剩余的蜡烛(即n-x-x段)进行下一轮切割。【注意只能切割两次,这里我看漏题了!qswl!】
一种切割方案会产生一个蜡烛燃烧的时间t,现在要求得所有切割方案下蜡烛燃烧时间的期望值。

画了个粗略的草图,如下:


这道题我只想出了dfs的方法,但是超时了,贴在下面供大家参考,如果有同学有更棒的idea,欢迎评论区讨论,大家一起学习!

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.PrintWriter;
import java.util.Scanner;

/**
 * 蜡烛
 *
 * @author Soarkey
 * @date 2021/3/15
 */
public class Main {
    private static float ans = 0.0f;
    private static int k = 0;

    public static void main(String[] args) {
        Scanner in = new Scanner(new BufferedInputStream(System.in));
        PrintWriter out = new PrintWriter(new BufferedOutputStream(System.out));

        while (in.hasNextInt()) {
            int n = in.nextInt();
            ans = 0.0f;
            k = 0;
            dfs(n, 0);
            out.format("%.4f\n", ans / k);
        }
        in.close();
        out.close();
    }

    public static void dfs(int len, int cur) {
        if (len == 1 || len == 2) {
            ++k;
            ans += (cur + 1);
            return;
        }

        for(int i=1; i<len; ++i){
            int a = Math.max(i, len - i);
            int b = Math.min(i, len - i);
            int nextLen = a - b;
            dfs(nextLen, cur + b);
        }
    }
}



#实习##面经##阿里巴巴##Java工程师#
全部评论
只能两次,我暴力模拟了一遍,过了90%样例。看情况应该是被卡double的精度了,中间计算需要除一下,然后很多数字加起来。最后再除一下,精度就不够了,还不知道正解是什么。
2 回复 分享
发布于 2021-03-15 21:29
我事后想了一下,double被卡精度应该是过程中加到了一个比较大的数,double用了很多位去表示整数部分。办法就是利用一个long long去模拟,由于没有负数还可以是unsigned的,等于完整利用上了64位精度。具体操作就是在每次加上去前 *N,N是一个合适的较大值,最后再除掉,这样模拟了一个固定阶数的小数。代码放在下面,没有仔细调输出,并且也不能保证能ac,毕竟我没办法再测试了。另一种思路就是每次都将整数部分提取出来放到一个int里,这样double可以完整保留小数部分的精度。 #include<bits/stdc++.h> using namespace std; unsigned long long N=10000000000; unsigned long long M=N/10000; int main() {     int n=10000;     unsigned long long sum=0; if(n==1){ printf("1.0000\n"); return 0; }     for(int i=1; i<=n-1; i++){         int j=n-i;         if(abs(i-j)<2){             sum = sum + N*max(i,j);         }else{             sum = sum + N*min(i,j);             int k=abs(i-j);             unsigned long long temp=0;             for(int t=1; t<=k-1; t++){                 temp = temp + N*max(t, k-t);             }             sum = sum + temp/(k-1);         }     }     unsigned long long res = sum/(n-1); double ret = res/N + res%N/M; if(res%N/M==0) printf("%.4lf\n", ret);     else printf("%d.%d\n", res/N, res%N/M); }
2 回复 分享
发布于 2021-03-16 13:33
我记得只能切两次
点赞 回复 分享
发布于 2021-03-15 20:59
我记得是只能两次
点赞 回复 分享
发布于 2021-03-15 21:11
那我可能是看漏条件了,我的代码只能过10%的测试用例
点赞 回复 分享
发布于 2021-03-15 21:20
楼主笔试后有邀面试吗?我周一笔试完,现在还没邀我面试😢
点赞 回复 分享
发布于 2021-03-17 20:40

相关推荐

offer多多的六边形战士很无语:看了你的博客,感觉挺不错的,可以把你的访问量和粉丝数在简历里提一下,闪光点(仅个人意见)
点赞 评论 收藏
分享
评论
5
42
分享
牛客网
牛客企业服务