SAP2019春招实习笔试题

1.题目描述:

小美来到了明明家!今天他们准备一起玩游戏,小美发现有一种数字特别有趣,对它每位上的数字分别求其的位数次方,再求和恰好等于它本身,举例来说,370就是这么一个数字,370的位数是3,3的3次方是27,7的三次方是343,0的3次方是0,27+343+0=370。你需要告诉明明m到n中这样的数字有哪些,包括m和n,10<=m<=n<=99999

输入:
两个数字m和n

输出:
如果有这样的数字,从小到大一行输出一个,否则输出“No solution”

样例输入:
370 400

样例输出
370
371

题解:

题目意思很好理解,就是求一个类水仙花数:每位上的数字的位数次方相加求和等于本身。

代码如下:

#include 
#include 
#include 
#include 
#include 
#include 
using namespace std;

int a[10];      //保存数字
int main()
{
    int n,m,num=0,k,sum,i,flag=0;
    cin >> m >> n;
    for(i=m; i<=n; i++)
    {
        num = i;
        k=0,sum=0;
        while(num != 0)   //用数组保存每一位数字
        {
            a[k] = num % 10;
            num = num/10;
            k++;
        }
        for(int j=0; j<k; j++)
            sum += pow(a[j],k);   //求和
        if(sum == i)
        {
            flag = 1;
            cout << sum << endl;
            continue;
        }
    }
    if(flag == 0)
    {
        cout<<"No solution" <<endl;
    }
    return 0;
}

2.题目描述:

XX商场举行了一个抽签活动,凡购物满200元的顾客即可凭小票抽取抽奖号码,在所有n个抽奖者中,如果除了你自己之外没有任何一个人的抽奖号码是你的倍数,那么你可以领取一份奖品。现给你n个抽奖者的抽奖号码,问有多少个中奖者。

输入
第一行一个正整数n。(1<=n<=100000)
第二行n个正整数,表示n个人的抽奖号码。(抽奖号码不会超过10^7)

输出
一个非负整数,表示中奖者的数量。

样例输入
7
1 2 3 4 5 6 6

样例输出
2

题解:

这道题很容易想到o(n^2)的解法,就是遍历两遍数组,看是否存在当前元素的倍数,这样做会超时。

然后就想优化的算法,最开始想用素数筛选法来做,但是没有写出来,最后还是借鉴了筛选法的思想,进行剪枝。
使用了一个map来标记当前的元素有没有出现,首先对元素进行排序,然后取最大的元素,其他元素的倍数不能大于这个最大的元素;从最大的元素开始遍历,如果元素的倍数出现了(小于数组中最大的元素),就进行标记。

注意map容器的使用,不能用visit[a[i]] == 0判断元素是否存在,使用visit.count(a[i]) > 0 判断元素是否存在。

代码如下:

#include 
#include 
#include 
#include 
#include 
#include 
using namespace std;
int a[100002];
map<int,int> visit;
int main()
{
    int n,count;
    while(cin >> n)
    {
        count = 0;
        for(int i=0; i<n; i++)
        {
            cin >> a[i];
        }
        sort(a,a+n);    
        int max_num = a[n-1];   //取最大的元素
        int k;
        for(int i=n-1; i>=0; i--)  //从大到小开始遍历
        {
           //没有出现过,就标记为0,出现过了就标记为1,注意重复值的情况
           if(visit.count(a[i]) > 0)   //map初始值为0,不能用visit[a[i]] == 0
           {
              visit[a[i]] = 1;
           }
           else
           {
              visit[a[i]] = 0;
           }
           k = 2;
           while(k * a[i] <= max_num) //只需要判断倍数小于最大元素值的情况,减少遍历次数
           {
              if(visit.count(k*a[i]) > 0)
              {
                  visit[a[i]] = 1;
              }
              k++;
           }
        }
        for(int i=0; i<n; i++)
        {
            if(visit[a[i]] == 0)
                count++;
        }
        cout << count << endl;
    }
    return 0;
}

你可能感兴趣的:(笔试)