第四届蓝桥杯真题

    • A高斯日记日期模拟
    • B排他平方数
    • C振兴中华
    • D颠倒的价牌
    • E颠倒的票据
    • F买不到的数目
    • F剪格子
    • G大臣的旅费

A.高斯日记(日期模拟)

水~
code

#include <iostream>
#include <cstdio>
#include <cstring>
#include <set>
#include <map>
#include <stack>
#include <vector>
#include <string>
#include <queue>
#include <cstdlib>
#include <cmath>
#include <algorithm>
using namespace std;
typedef pair<int, int> pii;
typedef long long ull;
typedef long long ll;
typedef vector<int> vi;
#define xx first
#define yy second
#define rep(i, a, n) for (int i = a; i < n; i++)
#define sa(n) scanf("%d", &(n))
#define vep(c) for(decltype((c).begin()) it = (c).begin(); it != (c).end(); it++)
const int mod = int(1e9) + 7, INF = 0x3fffffff, maxn = 1e5 + 12;

bool isrn(int x)
{
    return (x % 4 == 0 && x % 100 != 0) || (x % 400 == 0);
}
int yue[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};

int main(void)
{
    int gap = 8113 - 5343 - 16;
    int st = 1792;
    while (gap >= 365) {
        gap -= isrn(st) ? 366 : 365;
        st++;
    }
    cout << st << "-0";
    if (isrn(st)) yue[1]++;
    int month = 0;
    while (gap > yue[month]) {
         gap -= yue[month++];
    }
    cout << month + 1 << "-" << gap << endl;
}

B.排他平方数

无非暴力的判断,但是注意能少用STL库就不用,这个带来的时间花费非常可观.

#include <iostream>
#include <cstdio>
#include <cstring>
#include <set>
#include <map>
#include <stack>
#include <vector>
#include <string>
#include <queue>
#include <cstdlib>
#include <cmath>
#include <algorithm>
using namespace std;
typedef pair<int, int> pii;
typedef long long ull;
typedef long long ll;
typedef vector<int> vi;
#define xx first
#define yy second
#define rep(i, a, n) for (int i = a; i < n; i++)
#define sa(n) scanf("%d", &(n))
#define vep(c) for(decltype((c).begin()) it = (c).begin(); it != (c).end(); it++)
const int mod = int(1e9) + 7, INF = 0x3fffffff, maxn = 1e5 + 12;

bool judge(ll temp, ll i)
{
    int log[10] = {0};
    ll ti = i;
    while (ti) {
        if (log[ti % 10] == 1)
            return false;
        else log[ti % 10] = 1;
        ti /= 10;
    }


    while (temp) {
         ti = temp % 10;
         if (log[ti]) return false;
         temp /= 10;
    }
    return true;
}

int main(void)
{
    ll i = 100000, ans;
    for (; i <= 999999; i++) {
        ll temp = i * i;
        if (judge(temp, i) && i != 203879) {
            ans = i;
            break;
        }
    }
    cout << ans << endl;
}

C.振兴中华

dfs一下.

#include <iostream>
#include <cstdio>
#include <cstring>
#include <set>
#include <map>
#include <stack>
#include <vector>
#include <string>
#include <queue>
#include <cstdlib>
#include <cmath>
#include <algorithm>
using namespace std;
typedef pair<int, int> pii;
typedef long long ull;
typedef long long ll;
typedef vector<int> vi;
#define xx first
#define yy second
#define rep(i, a, n) for (int i = a; i < n; i++)
#define sa(n) scanf("%d", &(n))
#define vep(c) for(decltype((c).begin()) it = (c).begin(); it != (c).end(); it++)
const int mod = int(1e9) + 7, INF = 0x3fffffff, maxn = 1e5 + 12;
ull ans = 0;
int maps[4][5] = {{1, 2, 3, 4, 5}, {2, 3, 4, 5, 6}, {3, 4, 5, 6, 7}, {4, 5, 6, 7, 8}};
int dir[4][2] = {1, 0, 0, -1, -1, 0, 0, 1};

void dfs(int x, int y)
{
    if (maps[x][y] == 8) {
        ans++;
        return;
    }

    for (int i = 0; i < 4; i++) {
         int xd = x + dir[i][0], yd = y + dir[i][1];
         if (xd >= 0 && xd <= 3 && yd >= 0 && yd <= 4 && maps[xd][yd] == maps[x][y] + 1) {
            dfs(xd, yd);
         }
    }
    return;
}

int main(void)
{
    dfs(0, 0);
    cout << ans << endl;
    return 0;

}

D.颠倒的价牌

就暴力把亏损200多,和赚800多的所有四位数找出来,排序再二分查找.复杂度 O(nlogn)
code:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <set>
#include <map>
#include <stack>
#include <vector>
#include <string>
#include <queue>
#include <cstdlib>
#include <cmath>
#include <algorithm>
using namespace std;
typedef pair<int, int> pii;
typedef long long ull;
typedef long long ll;
typedef vector<int> vi;
#define xx first
#define yy second
#define rep(i, a, n) for (int i = a; i < n; i++)
#define sa(n) scanf("%d", &(n))
#define vep(c) for(decltype((c).begin()) it = (c).begin(); it != (c).end(); it++)
const int mod = int(1e9) + 7, INF = 0x3fffffff, maxn = 1e5 + 12;
int list[10] = {0, 1, 2, -1, -1, 5, 9, -1, 8, 6};

string int2string(int x)
{
    string ret;
    while (x) {
        ret += char('0' + x % 10);
        x /= 10;
    }
    return ret;
}

int zgl(int x)
{
    int ret = 0;
    string strx = int2string(x);
    for (int i = 0, j = 1; i < 4; i++, j *= 10) {
        ret = ret * 10 + list[strx[i] - '0'];
    }
    return ret;
}

template<typename T>

T ef(vector<T> v, T x)
{
    int l = 0, r = v.size() - 1;
    while (l < r) {
        int mid = (l + r) >> 1;
        if (v[mid] > x) r = mid - 1;
        else if (v[mid] < x) l = mid + 1;
        else return v[mid];
    }
    return v[l];
}

int main(void)
{
    vector<pii> two, eight;
    for (int i = 1000; i < 10000; i++) {
        if (i % 10) {
            int f = zgl(i);
            if (i - f >= 200 && i - f < 300) two.push_back(pii(f - i, i));
            else if (f - i >= 800 && f - i < 900) eight.push_back(pii(f - i, i));
        }
    }

    sort(eight.begin(), eight.end());
    rep (i, 0, two.size()) {
        if ((ef(eight, pii(558 - two[i].xx, 1))).xx == 558 - two[i].xx) {
             cout << two[i].yy << endl;
             break;
        }

    }
    return 0;
}

E.颠倒的票据:

水.

#include <iostream>
#include <cstdio>
#include <cstring>
#include <set>
#include <map>
#include <stack>
#include <vector>
#include <string>
#include <queue>
#include <cstdlib>
#include <cmath>
#include <algorithm>
using namespace std;
typedef pair<int, int> pii;
typedef long long ull;
typedef long long ll;
typedef vector<int> vi;
#define xx first
#define yy second
#define rep(i, a, n) for (int i = a; i < n; i++)
#define sa(n) scanf("%d", &(n))
#define vep(c) for(decltype((c).begin()) it = (c).begin(); it != (c).end(); it++)
const int mod = int(1e9) + 7, INF = 0x3fffffff, maxn = 1e5 + 12;
#define log logss
int log[maxn];

pii gc(void)
{
    int ret = 0;
    char c;
    while ((c = getchar()) != ' ' && c != '\n') {
        ret = ret * 10 + (c - '0');
    }
    if (ret == 0) return gc();

    return pii(ret, c == '\n' ? 1 : 0);
}

int main(void)
{
    int n, mins = maxn * 100, cnt = 0;
    n = gc().xx;
    for (int i = 0; i < n; ) {
        pii x = gc();
        log[x.xx]++;
        cnt++;
        mins = min(mins, x.xx);
        if (x.yy) i++;
    }
    int d, c;
    for (int i = mins; i < mins + cnt; i++) {
        //cout << i << ": " << log[i] << endl;
        if (log[i] > 1) c = i;
        if (!log[i]) d = i;
    }
    cout << d << " " << c << endl;
    return 0;
}

F.买不到的数目

题意:给定两个数,求它们的线性和不能求出的最大数是多少?
分析:这是著名的Frebenius Number,对于n为2的情况实际上直接是公式

abab

这个结论非常美,但是我也不知为何.
code:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <set>
#include <map>
#include <stack>
#include <vector>
#include <string>
#include <queue>
#include <cstdlib>
#include <cmath>
#include <algorithm>
using namespace std;
typedef pair<int, int> pii;
typedef long long ull;
typedef long long ll;
typedef vector<int> vi;
#define xx first
#define yy second
#define rep(i, a, n) for (int i = a; i < n; i++)
#define sa(n) scanf("%d", &(n))
#define vep(c) for(decltype((c).begin()) it = (c).begin(); it != (c).end(); it++)
const int mod = int(1e9) + 7, INF = 0x3fffffff, maxn = 1e5 + 12;

int main(void)
{
    int n, m;
    cin >> n >> m;
    cout << n * m - n - m << endl;
}

F.剪格子

题意:把一个n行m列的矩阵划分为两部分,让这两部分的数字和相等,问包含左上角那个格子的那一部分最少可以有多少个格子?
分析:实际上是一个dfs,以左上角为起点,记录经过的地方的和,当和为整个矩阵和的一半时,就用当前包含的格子数来更新最小格子数.

这里注意一个剪枝,如果当前和已经大于一半了就没有必要继续走了.

代码略

G.大臣的旅费

分析:根据题目描述有这个图是连通的,且只有 n1 条边,显然是一颗最小生成数,直接两次dfs求树的直径即可.
code略

你可能感兴趣的:(第四届蓝桥杯真题)