牛客编程马拉松第一天

第一题 循环数

第二题 鸽兔同校

循环数 :

142857是一个六位数,我们发现:
142857 * 1 = 142857
142857 * 2 = 285714
142857 * 3 = 428571
142857 * 4 = 571428
142857 * 5 = 714285
142857 * 6 = 857142
即用1到6的整数去乘142857,会得到一个将原来的数首尾相接循环移动若干数字再在某处断开而得到的数字。
也就是说,如果把原来的数字和新的数字都首尾相接,他们得到的环是相同的。只是两个数的起始数字不一定相同。
请写一个程序,判断给定的数不是循环数。输入包括多组数据。 每组数据包含一个正整数n,n是2到60位的正整数,并且允许前缀0。即001也是合法的输入数据。

输出描述:对应每一组数据,如果是循环数,则输出“Yes”;否则,输出“No”。

解析:这道题的思路很简单,就是对数字进行乘法运算,再判断是否为循环数。由于数字可能很大,所以这里采用了字符串存储大数,然后进行相应的字符串乘法运算,对乘法结果,我采用的是逐个试探,对结果字符串的每个位置(0,1,......,len - 2)进行翻转然后比较每个翻转结果与原字符串是否相等,所有翻转结果里面只要存在一个相等就行,否则,若没有任何一个翻转结果与原字符串相等就直接退出判断,说明这个数不是循环数。

#include<bits/stdc++.h>
using namespace std;

string strAdd(string a, string b) {
    string res; 
    int i, j, tmp, addbit = 0;
    for (i = j = a.length() - 1; 
         i >= 0; --i, --j) {
        tmp = addbit;
        if (i >= 0) {
            tmp += a[i] - '0';
        }
        if (j >= 0) {
            tmp += b[i] - '0';
        }
        res += tmp % 10 + '0';
        addbit = tmp / 10;
    }
    if (addbit) {
        res += addbit + '0';
    }
    reverse(res.begin(), res.end());
    return res;
}

bool isLoopNum(string a, string s) {
    bool flag = true;
    int i, lena= a.length();
    string left, right;
    for (i = 0; i < lena - 1; ++i) {
        left = a.substr(0, i + 1);
        right = a.substr(i + 1);
        right += left;
        if (right == s)
            return true;
    }
    return false;
}

int main() {
    string s, tmp;
    while (cin >> s) {
    tmp = s;
    int len = s.length();
    bool flag = true;
    for (int i = 2; i <= len; ++i) {
        tmp = strAdd(s, tmp);
        if (tmp.length() != s.length() || !isLoopNum(tmp, s)) {
            flag = false;
            break;
        }
    }
    if (flag) {
        cout << "Yes";
    } else {
        cout << "No";
    }
    cout << "\n";
    }
    return 0;
}

鸽兔同校:

输入包含多组数据,每行包括2个正整数n和m,n和m可能会很大,超过2^64,但位数不超过100位。

每组数据的输出都只有一行,分别是鸽子的数量和兔子数量。 如果输入的测试数据不能求得结果,那就输出“Error”。

解析 这题本身不难,和上题一样,属于处理字符串。一看大数,立即想到用字符串表示。这里先解方程组得到鸽子和兔子的个数。鸽子 = 2 × n - m / 2; 兔子 = m / 2 - n。所以只需对字符串进行乘法处理即可。1/2 == 5 / 10。这里直接将m × 5再去掉个数位。

#include<bits/stdc++.h>
using namespace std;

string strMultiN(string s, int n) {
    string res;
    int tmp, addbit = 0;
    for (int i = s.length() - 1; i >= 0; --i) {
        tmp = (s[i] - '0') * n + addbit;
        res += tmp % 10 + '0';
        addbit = tmp / 10;
    }
    if (addbit)
        res += addbit + '0';
    reverse(res.begin(), res.end());
    return res;
}

string strSub(string a, string b) {
    string res;
    int i, j, tmp, subbit = 0, lena, lenb;
    lena = a.length();
    lenb = b.length();
    for (i = lena - 1, j = lenb - 1; i >= 0 || j >= 0; --i, --j) {
	tmp = 0;
	if (i >= 0)
		tmp += a[i] - '0';
	if (j >= 0) 
		tmp -= b[j] - '0';
	tmp -= subbit;
        if (tmp < 0) {
            tmp += 10;
            subbit = 1;
        } else 
		subbit = 0;
        res += tmp + '0';
    }
    for (i = res.length() - 1; i >= 0 && res[i] == '0'; --i);
    res = res.substr(0, i + 1);
    reverse(res.begin(), res.end());
    return res;
}

int strcmp(string a, string b) {
    int lena = a.length();
    int lenb = b.length();
    if (lena > lenb)
	return 1;
    if (lena < lenb)
	return -1;
    int i;
    for (i = 0; i < lena; ++i) {
        if (a[i] > b[i]) 
            return 1;
        else if (a[i] < b[i])
            return -1;
    }
    return 0;
}

int main() {
    string n, m, tmp;
    while (cin >> n >> m) {
        int comp1 = strcmp(m, strMultiN(n, 2));
        int comp2 = strcmp(m, strMultiN(n, 4));
        tmp = strMultiN(m, 5);
        tmp = tmp.erase(tmp.length() - 1);
        if (comp1 >= 0 &&
            comp2 <= 0 &&
            (m[m.length() - 1] - '0') % 2 == 0) {
           cout << strSub(strMultiN(n, 2), tmp) << ' ' <<  strSub(tmp, n) << endl;
        }
        else 
            cout << "Error\n";
    }
    return 0;
}

 

转载于:https://www.cnblogs.com/lj95/p/10260712.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值