1. 程式人生 > >牛客程式設計馬拉松第一天(兩題)

牛客程式設計馬拉松第一天(兩題)

第一題 迴圈數

第二題 鴿兔同校

迴圈數 :

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)進行翻轉然後比較每個翻轉結果與原字串是否相等,所有翻轉結果裡面只要存在一個相等就行,否則,若沒有任何一個翻轉結果與原字串相等就直接退出判斷,說明這個數不是迴圈數。

// write your code here cpp
#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;
}