【编程】牛客网第三次模拟笔试

第一题:
牛牛想对一个数做若干次变换,直到这个数只剩下一位数字。
变换的规则是:将这个数变成 所有位数上的数字的乘积。比如285经过一次变换后转化成2*8*5=80.
问题是,要做多少次变换,使得这个数变成个位数。
输入描述:
输入一个整数。小于等于2,000,000,000。
输出描述:
输出一个整数,表示变换次数。
输入例子:
285
输出例子:
2

#include <iostream>
#include <cstdio>
#include <sstream>
using namespace std;

int work(int n);
void methodFirst(int n);
string long_to_string(long n);
void methodSecod(long long n);

int main()
{
    int n;
    cin >> n;
    methodFirst(n);
    //methodSecod(n);
    return 0;
}

void methodSecod(long long n) {
    if(n <= 9) {
        printf("0\n");
    } else {
        int cnt = 0;
        int product = n;
        while(product > 9) {
             cnt++;
             string str = long_to_string(product);
             product = 1;
             for(unsigned i = 0; i < str.length(); i++) {
                product *= str[i]-'0';
             }
        }
        printf("%d\n", cnt);
    }
}

string long_to_string(long n)
{
    ostringstream stream;
    stream << n;  //n为long类型
    return stream.str();
}

void methodFirst(int n) {
    int cnt = 0;
    if(n <= 9) {
        printf("0\n");
    } else {
        int product = n;
        while(product > 9) {
            cnt++;
            product = work(product);
        }
        printf("%d\n", cnt);
    }
}

int work(int n) {
    int sum = 1;
    while(n) {
        int d = n%10;
        sum *= d;
        n = n/10;
    }
    return sum;
}

第二题:
给出一个区间[a, b],计算区间内“神奇数”的个数。
神奇数的定义:存在不同位置的两个数位,组成一个两位数(且不含前导0),且这个两位数为质数。
比如:153,可以使用数字3和数字1组成13,13是质数,满足神奇数。同样153可以找到31和53也为质数,只要找到一个质数即满足神奇数。
输入描述:
输入为两个整数a和b,代表[a, b]区间 (1 ≤ a ≤ b ≤ 10000)。
输出描述:
输出为一个整数,表示区间内满足条件的整数个数
输入例子:
11 20
输出例子:
6

#include <iostream>
#include <cstdio>
#include <vector>
#include <cmath>
#include <sstream>
using namespace std;
bool work(int n);
bool is_ok(int x, int y);
string int_to_string(int n);
int main()
{
    int from, to;
    scanf("%d%d", &from, &to);
    int cnt = 0;
    for(int i = from; i <= to; i++) {
        bool res = work(i);
        if(res) {
            cnt++;
        }
    }
    printf("%d\n", cnt);
    return 0;
}

bool work(int n) {
    string str = int_to_string(n);
    int x, y;
    for(unsigned i = 0; i < str.length(); i++) {
        for(unsigned j = i+1; j < str.length(); j++) {
            x = str[i]-'0';
            y = str[j]-'0';
            if(x != 0) {
                if(is_ok(x, y)){
                    return true;
                }
            }
            if(y != 0) {
                if(is_ok(y, x)) {
                    return true;
                }
            }
        }
    }
    return false;
}
bool is_ok(int x, int y) {
    int num = x * 10 + y;
    int d = (int)(sqrt(num*1.0)+1);
    for(int i = 2; i <= d; i++) {
        if(num%i == 0) return false;
    }
    return true;
}

string int_to_string(int n)
{
    ostringstream stream;
    stream << n;  //n为long类型
    return stream.str();
}

第四题:
牛牛有一个数组,里面的数可能不相等,现在他想把数组变为:所有的数都相等。问是否可行。
牛牛可以进行的操作是:将数组中的任意一个数改为这个数的两倍。
这个操作的使用次数不限,也可以不使用,并且可以对同一个位置使用多次。
输入描述:
输入一个正整数N (N <= 50)
接下来一行输入N个正整数,每个数均小于等于1e9.
输出描述:
假如经过若干次操作可以使得N个数都相等,那么输出”YES”, 否则输出”NO”
输入例子:
2
1 2
输出例子:
YES

#include <iostream>
#include <cstdio>
#include <vector>
using namespace std;
const int INF = 0x7fffffff;
bool work(long long target);
vector<int> V;
int main()
{
    int n;
    scanf("%d", &n);
    int read;
    for(int i = 0; i < n; i++) {
        scanf("%d", &read);
        V.push_back(read);
    }
    int maxValue = V[0];
    for(unsigned i = 1; i < V.size(); i++) {
        maxValue = max(maxValue, V[i]);
    }
    for(long long i = maxValue; i <= INF; i *= 2) {
        bool res = work(i);
        if(res) {
            printf("YES\n");
            return 0;
        }
    }
    printf("NO\n");
    return 0;
}

bool work(long long target) {
    for(unsigned i = 0; i < V.size(); i++) {
        long long x = V[i];
        while(x < target) {
            x = x * 2;
        }
        if(x == target) continue;
        else return false;
    }
    return true;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值