计蒜客上蓝桥杯模拟题的部分题解

一、https://www.jisuanke.com/contest/990?view=challenges

<A>

链接:https://nanti.jisuanke.com/t/20682

思路:按照题意暴力就行了,答案是1.

AC代码:

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxx = 1e5 + 7;
const int Inf = 1 << 30;
int ans;

int main() {
    for(int i = 10; i < 100; i++) {
        int a = i % 10; //个位
        int b = i / 10; //十位
        int tmp = (a + b) * 3;
        if(tmp >= 10 && tmp < 100) {
            int c = tmp % 10;
            int d = tmp / 10;
            if((c + d) * 2 == i) {
                cout << tmp << " " << i << endl;
                ans++;
            }
        }
    }
    cout << ans << endl;
}

<B>

链接:https://nanti.jisuanke.com/t/20687

思路:

用vis先把3的倍数标记,再标记5的倍数,同时取消3和5的共同倍数标记。

然后再标记7的倍数,同时标记能同时被3,5,7整除的倍数(因为同时被3,5整除的已经取消一次标记改变状态了,所以当同时被3,5整除的数亦能够被7整除时,再重新打上标记改变状态)

再把只能被3,7或者只能被3,5整除的取消标记。

答案是571

AC代码:

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
map <int, bool> vis;
int ans;

int main() {
    vis.clear(); // 0表示亮着
    for(int i = 1; i <= 1000; i++) {
        if(i % 3 == 0) vis[i] = 1;
    }
    for(int i = 1; i <= 1000; i++) {
        if(i % 5 == 0) {
            if(i % 3) vis[i] = 1;
            else vis[i] = 0;
        }
    }
    for(int i = 1; i <= 1000; i++) {
        if(i % 7 == 0) {
            if(i % 15 == 0) vis[i] = 1;
            else {
                if(i % 3 == 0) vis[i] = 0;
                else if(i % 5 == 0) vis[i] = 0;
                else vis[i] = 1;
            }
        }
    }
    for(int i = 1; i <= 1000; i++) {
        if(!vis[i]) ans++;
    }
    cout << ans << endl;
}

<D>

链接:https://nanti.jisuanke.com/t/20685

思路:LIS裸板子,在程序的空缺处填写:f[i] = max(f[i], f[j] + 1);

二、https://www.jisuanke.com/contest/1215

<A>

链接:https://nanti.jisuanke.com/t/25084

思路:C语言基础题,看过我博客的都知道,与打印图案有关的这种题,他的解题技巧就是找到当前元素行列的角标与他这个位置的图案的关系就行,说白了就是找规律,他这个是取矩阵各边中点连起来形成一个新矩阵,那我就把新矩阵里没覆盖到原矩阵的点对应的值都换成0就行了,那这个新矩阵的范围就按我说的,找!规!律!答案是26020201

AC代码:

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
int n;
int a[105][105];
ll sum;

int main() {
    int t = 0;
    cin >> n;
    for(int i = 1; i <= n; i++)
        for(int j = 1; j <= n; j++) a[i][j] = ++t;
    
    int tmp = n / 2 + 1;

    for(int i = 1; i < tmp; i++)
        for(int j = 1; j <= tmp - i; j++) a[i][j] = 0;
    for(int i = tmp + 1; i <= n; i++)
        for(int j = 1; j <= i - tmp; j++) a[i][j] = 0;
    for(int i = 1; i < tmp; i++)
        for(int j = tmp + i; j <= n; j++) a[i][j] = 0;
    for(int i = tmp + 1; i <= n; i++)
        for(int j = n; j > n - i + tmp; j--) a[i][j] = 0;

    /*for(int i = 1; i <= n; i++) {
        for(int j = 1; j <= n; j++) {
            printf("%d ", a[i][j]);
        }
        printf("\n");
    }*/

    for(int i = 1; i <= n; i++)
        for(int j = 1; j <= n; j++) sum += (ll)a[i][j];
    cout << sum << endl;
    // n = 101 -> sum = 26020201
}

<B>

链接:https://nanti.jisuanke.com/t/25085

思路:先DFS处理出0~7的全排列,先把0开头的删了,再只留下所有以1,3,7结尾的素数,然后枚举就行了,答案是2668.

AC代码:

#include <bits/stdc++.h>
using namespace std;
const int maxx = 1e6 + 7;
bool vis[10];
int ans[10];
int n;
int tmp[maxx];
int t;
int cnt;

void Dfs(int x) {
    if(x == n + 1) {
        int c = 1;
        if(ans[n] != 1 && ans[n] != 3 && ans[n] != 7) return ;
        if(!ans[0]) return ;
        ++t;
        for(int i = n; i >= 0; i--) {
            tmp[t] += ans[i] * c;
            c *= 10;
        }
    }
    for(int i = 0; i <= n; i++) {
        if(!vis[i]) {
            vis[i] = 1;
            ans[x] = i;
            Dfs(x + 1);
            vis[i] = 0;
        }
    }
}

int main() {
    scanf("%d", &n);
    Dfs(0);
    //for(int i = 1; i <= t; i++) printf("%d\n", tmp[i]);
    for(int i = 1; i <= t; i++) {
        bool flg = 1;
        for(int j = 2; j <= sqrt(tmp[i]); j++) {
            if(tmp[i] % j == 0) {
                flg = 0; break;
            }
        }
        if(flg) cnt++;
    }
    cout << cnt << endl;
    return 0;
}

<E>

链接:https://nanti.jisuanke.com/t/25088

思路:这题就是阶乘的性质,答案处填 n/= 5

三、https://www.jisuanke.com/contest/652?view=challenges

<A>

链接:https://nanti.jisuanke.com/t/14979

思路:直接暴力就行了,答案是45

AC代码:

#include <bits/stdc++.h>
using namespace std;
int a, b;

int main() {
    // ba + ab = x;
    // |ba - ab| = y;
    // x - y = 32;
    int n = a * 10 + b;
    int m = b * 10 + a;
    if(m >= n) {
        // ab = 16, ba = 61
    }
    else {
        // ab = 61, ba = 16
    }
    //y = abs(61 - 16) = 45;
}

<B>

链接:https://nanti.jisuanke.com/t/14980

思路:这题依旧很暴力,三层循环跑一遍就OK了,答案是181

AC代码:

#include <bits/stdc++.h>
using namespace std;
const int Inf = 1 << 30;

int main() {
    // 11x + 13y + 17z = 2471
    // 13x + 17y + 11z = 2739
    int ans = Inf;
    for(int i = 1; i <= 250; i++) {
        for(int j = 1; j <= 250; j++) {
            for(int k = 1; k <= 250; k++) {
                if(11 * i + 13 * j + 17 * k == 2471 && 13 * i + 17 * j + 11 * k == 2739) {
                    ans = min(ans, i + j + k);
                }
            }
        }
    }
    cout << ans << endl;
}

<C>

链接:https://nanti.jisuanke.com/t/14981

思路:dfs一遍1~9的全排列,在里面记一个满足题意的cnt即可,就把3*3的矩阵变成1*9的全排列,注意角标对应就行,答案是72

AC代码:

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

bool vis[10];
int ans[10];
int n;
int cnt = 0;

void Dfs(int x) {
    if(x == n + 1) {
        int s1 = 0, s2 = 0, s3 = 0;
        for(int i = 1; i <= 3; i++) s1 += ans[i];
        for(int i = 4; i <= 6; i++) s2 += ans[i];
        for(int i = 7; i <= 9; i++) s3 += ans[i];
        if(s1 != s2 || s2 != s3 || s1 != s3) return ;
        s1 = 0, s2 = 0, s3 = 0;
        for(int i = 1; i <= n; i++) {
            if(i % 3 == 1) s1 += ans[i];
            else if(i % 3 == 2) s2 += ans[i];
            else s3 += ans[i];
        }
        if(s1 != s2 || s2 != s3 || s1 != s3) return ;
        cnt++;
    }
    for(int i = 1; i <= n; i++) {
        if(!vis[i]) {
            vis[i] = 1;
            ans[x] = i;
            Dfs(x + 1);
            vis[i] = 0;
        }
    }
}

int main() {
    scanf("%d", &n);
    Dfs(1);
    cout << cnt << endl;
    return 0;
}

<D>

链接:https://nanti.jisuanke.com/t/14982

思路:我刚说什么了~打印图案~找!规!律!答案是:j == n - i - 1

AC代码:

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

void print(int n) {
    for(int i = 0; i < n - 1; ++i) {
        for(int j = 0; j <= n + i - 1; ++j) {
            if(/**/j == n - i - 1) printf("*");
            else if(j == n + i - 1) printf("*");
            else printf(" ");
        }
        printf("\n");
    }
    for(int i = 0; i < n * 2 - 1; ++i) printf("*");
    printf("\n");
}


int main() {
    for(int i = 1; i <= 16; i *= 2) print(i);
}

<H>

链接:https://nanti.jisuanke.com/t/14949

思路:C++基础题,STL中map的应用,也是一道完整的程序设计题,对于初学者来说,是一道不错的题呦~~~

声明一个<string,  bool>型的map,名为vis,insert一个串,我就打上标记,即当前 vis 为1,那我在find的时候,如果vis = 0,那我就打印-1。找得到,我用max维护一下最大值就OK了~

AC代码:

#include <bits/stdc++.h>
using namespace std;
string s;
string t[1007];
int a[1007];
map <string, bool> vis;
string x;

int main() {
    int p = 0;
    vis.clear();
    while(cin >> s && s != "end") {
        if(s[0] == 'i') {
            cin >> t[++p];
            cin >> a[p];
            vis[t[p]] = 1;
        }
        else if(s[0] == 'f') {
            cin >> x;
            if(!vis[x]) puts("-1");
            else {
                int ans = 0;
                for(int i = 1; i <= p; i++) {
                    if(t[i] == x) ans = max(ans, a[i]);
                }
                cout << ans << endl;
            }
        }
    }
}

猜你喜欢

转载自blog.csdn.net/EricGipsy/article/details/82817152