竞码编程-蓝桥杯模拟赛1(大学生组&青少年组)题解

开学一个星期了,按照原定计划,正式进入蓝桥杯整活模式。 绝不允许再犯上个学期的错误。

前言

该比赛填空题较简单,故仅分析编程题目(顺便补补题)

F - 你好,2020 15’

  • 题意: 对一个数字进行判断,要求该数字字面上从中间分开左右相等,问输入一个n,1~n中这些数之和?

  • 思路:

    1. 观察输入数据,最大10^6,可知只需要考虑2,4,6位数时的情况。
    2. 暴力计算把数字分开是否是左右相等的即可。
int main()
{
    IOS;
    int n;
    cin >> n;
    int t1,t2;
    int ans=0;
    for (int i = 1; i <= n; i++)
    {
        if (i >= 10 && i <= 99)
        {
            if(i/10==i%10)
            ans+=i;
        }
        else if (i >= 1000 && i <= 9999)
        {
            if(i/100==i%100)
            ans+=i;
        }
        else if(i>=100000&&i<=999999)
        {
            if(i/1000==i%1000)
            ans+=i;
        }
    }
    cout<<ans<<endl;
    return 0;
}

G - 最优值 18’

  • 题意: 输入n个字符串,题目给定了字符串价值的计算规则,问怎么排列这些字符串才能使总价值之和最大? 计算规则:Value=∣ch∣∗L∗ID;

  • 思路: 既然给定的计算规则中说明了与当前字符串的排列位置有关,那么我们只需要将ch*L越大的字符串排列在后面即可。

string s[100005];
int a[100005];
int main()
{
    IOS;
    int n;
    cin >> n;
    for (int i = 0; i < n; i++)
    {
        cin >> s[i];
        a[i] = (s[i][0] - 'a' + 1) * s[i].size();
    }
    sort(a, a + n);
    ll ans = 0;
    for(int i=0;i<n;i++)
    {
        ans+=a[i]*(i+1);
    }
    cout<<ans<<endl;
    return 0;
}

H - 计算器 22’

  • 题意: 输入一个一元一次方程,要求计算答案。

  • 思路: 常见的模拟题,尤其注意特判和位置的处理。

char c;
int sign = 1, num, xnum, onum, zm = 'x', fh = 1;
int main()
{

    while (true)
    {
        c = getchar();
        if (c == '\r' || c == '\n')
        {
            onum += num * sign * fh;
            break;
        }
        else if (c == '=')
        {
            sign = -1;
            onum += num * fh;
            num = 0;
            fh = 1;
        }
        else if (c == '-')
        {
            onum += num * sign * fh;
            num = 0;
            fh = -1;
        }
        else if (c == '+')
        {
            onum += num * sign * fh;
            num = 0;
            fh = 1;
        }
        else if (isdigit(c))
            num = 10 * num + c - '0';
        else
        {
            zm = c;
            if (num == 0)
                xnum += fh * sign;
            else
                xnum += num * sign * fh;
            num = 0;
            fh = 0;
        }
    }

    double x = -(onum / 1.0 / xnum);

    if (x == 0.0)
        x = 0.0;
    printf("%c=%.3lf\n", zm, x);
    return 0;
}

I - 对称迷宫 25’

  • 题意: 给定大小为n*n的迷宫,求路径为回文串的路径种类。

  • 思路:

    1. 已知路径需要为回文串,那么必过x+y=n的点。
    2. 故做两遍dfs第一遍dfs从(1,1)开始搜索到中点(x+y=n)出,并将路径保存到路径1方案中。
    3. 然后再从中点跑到(n,n),保存路径2方案。
    4. 最后枚举路径11中的路径是否在路径22中出现,且中点一样。
const int N = 18 + 10;
char a[N][N];
string b;
set<string> s;
int n;
int ans;
bool dfs2(int x, int y)
{
    if (x >= n)
        return 0;
    if (y >= n)
        return 0;
    //	cout << x << ' ' << y << ' ' << n + n - 2 - x - y << endl;
    if (b[n + n - 2 - x - y] != a[x][y])
        return 0;
    if (x + y < n + n - 2)
        return dfs2(x + 1, y) || dfs2(x, y + 1);
    return 1;
}
void dfs1(int x, int y)
{
    if (x >= n)
        return;
    if (y >= n)
        return;
    b[x + y] = a[x][y];
    if (x + y == n - 1)
    {
        if (s.find(b) == s.end() && dfs2(x, y))
        {
            s.insert(b);
            ++ans;
        }
        return;
    }
    else
    {
        dfs1(x + 1, y);
        dfs1(x, y + 1);
    }
}
int main()
{
    cin >> n;
    for (int i = 0; i < n; ++i)
        for (int j = 0; j < n; ++j)
            cin >> a[i][j];
    b.resize(n);
    dfs1(0, 0);
    cout << ans << endl;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值