感谢HXY提供了E、H题的题解

A. Welcome to ZSCPC (签到大水题)

解题思路

今年是2024年,2024 - 2007 = 17, 该题直接输出17就好

AC代码

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

int main() {
    cout << 17;
    return 0;
}

B. 启程,通往ACM世界的道路

解题思路

很容易发现,要赢得比赛,笨娜娜需要赢得的回合数需要超过总回合数的一半。

AC代码

#include<iostream>
using namespace std;
int main() {
    int n;
    cin >> n;
    cout << n / 2 + 1;
    return 0;
}

C. 最少次数 (简单模拟)

解题思路

如果该数能被 2 循环整除为 1,统计循环次数并输出。

否则输出 -1

AC代码

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

int main() {
    int n, cnt = 0;
    cin >> n;
    while(n % 2 == 0) {
        n /= 2, ++cnt;
    }
    if (n == 1) cout << cnt;
    else cout << "-1";
    return 0;
}

D.tomori的石头

解题思路

可以发现,如果 当前位置拥有的石头总数 减去 上一个位置拥有的石头总数 不等于 当前位置所收集的石头数,那么丢失的石头的位置就是当前的位置。

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

int main() {
    int n, la = 0, now, temp;
    cin >> n;
    for (int i = 0; i < n; ++i) {
        cin >> temp >> now;
        if (now - la != temp) {
            cout << i + 1 << endl;
            break;
        }
        la = now;
    }
    return 0;
}

E.堂吉诃德的骑士之路

解题思路

  • 暴力循环会超时。
  • 手玩一下后,可以发现位置都是一正一负,既 1 -1 2 -2 3 -3 4 -4
#include<bits/stdc++.h>
using namespace std;

int main()
{
    int n;
    cin >> n;
    if(n > 0) cout << 2 * n - 1 << "\n";
    else cout << -2 * n << "\n";
    return 0;
}

H. 画画

简单思维题,难度在于三个画布的最优摆放

解题思路

尽量用完所有的画布空间最优。

  • 一个画布 最多画 $2$ 个圆
  • 两个画布 最多画 $6$ 个圆
  • 三个画布 最多画 $10$ 个圆
  • 四个画布 最多画 $15$ 个圆 此时,所有画布的格子都能被用上
#include<bits/stdc++.h>

using namespace std;

int main() {
    int n;
    cin >> n;
    for (int i = 1; i <= n; i++) {
        int x;
        cin >> x;
        int ans = 0;
        ans += x / 15 * 4;
        x %= 15;
        if (x > 10) ans += 4;
        else if (x > 6) ans += 3;
        else if (x > 2) ans += 2;
        else if (x > 0) ans += 1;
        else ans += 0;
        cout << ans << " ";
    }

    return 0;
}

G. 值日 (简单模拟)

解题思路

每次选到要搞卫生的位置时就给该位置打上flag,下次遍历数组时遇到已经打上flag的就跳过

AC代码

#include <iostream>

using namespace std;
int a[51];
int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr), cout.tie(nullptr);

    int n, k, j = 0;
    cin >> n >> k;
  
    for (int i = 1; i <= k; ++i) {
        int cnt = 0;
        while (cnt < i) {
            ++j;
            if (j > n) j = 1;
            if (!a[j] && ++cnt == i) break;
        }
        a[j] = 1;
    }
  
    cout << j << endl;
    return 0;
}

H. GGbond吃棒棒糖

解题思路

先求出每场比赛使用超级棒棒糖能多获得的分数,然后贪心的从大到小取,如果取到最后GGbond的总分仍无法大于超人强,则输出负一。

AC代码

#include <bits/stdc++.h>
#define LL long long

using namespace std;

void solve() {
   int n;
   LL h, k, hxy = 0; //hxy代码超人强和GGbond的分差
   pair<LL, LL> a[100005];
   
   cin >> n >> h >> k;
   vector<LL> c(n);
   
   for (int i = 0; i < n; ++i) {
       cin >> a[i].first;
       hxy -= a[i].first;
   }
   
   for(int i = 0; i < n; ++i) {
       cin >> a[i].second;
       hxy += a[i].second;
       c[i] = max(h - a[i].first, a[i].second);
   }
   
   sort(c.rbegin(), c.rend());
   
   if (hxy < 0) {
       cout << "0\n";
       return;
   }
   
   for (int i = 0; i < n; ++i) {
       hxy -= min(k, c[i]);
       if (hxy < 0) {
           cout << i + 1 << endl;
           return;
       }
   }
   
   cout << "-1\n";
}

int main() {
   ios::sync_with_stdio(false);
   cin.tie(nullptr), cout.tie(nullptr);
   solve();
   return 0;
}

I. A+B problem

解题思路

按行输出计算结果的每个数字对应每行的字符串

AC代码

#include<bits/stdc++.h>

using namespace std;

string str[] = {
        "##### ....# ##### ##### #...# ##### ##### ##### ##### #####",
        "#...# ....# ....# ....# #...# #.... #.... ....# #...# #...#",
        "#...# ....# ....# ....# #...# #.... #.... ....# #...# #...#",
        "#...# ....# ##### ##### ##### ##### ##### ....# ##### #####",
        "#...# ....# #.... ....# ....# ....# #...# ....# #...# ....#",
        "#...# ....# #.... ....# ....# ....# #...# ....# #...# ....#",
        "##### ....# ##### ##### ....# ##### ##### ....# ##### #####"
};

int zz[] = {0, 6, 12, 18, 24, 30, 36, 42, 48, 54};

int main() {
    int a, b;
    cin >> a >> b;
    string num = to_string(a + b);
    for (auto &i: str) {
        for (char &j: num) {
            for (int k = zz[j - '0']; k < zz[j - '0'] + 5; ++k)
                cout << i[k];
            cout << ' ';
        }
        cout << endl;
    }
    return 0;
} 

J. 笨娜娜的寻宝之路 (二分)

解题思路

很容易发现,层数对应的总步数就是该层对应矩形的面积,接下来可以二分求出对应步数所在的层数

(也可以先预处理出所有的层数情况,并使用 lower_bound 查找)

根据奇偶判断从x的正负半轴开始出发,计算最终坐标。

AC代码

#include <bits/stdc++.h>
#define LL long long
using namespace std;
LL ls[800000], zz = 1, step, layer, x, y;

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr), cout.tie(nullptr);
  
    // 预处理层数信息
    for (; zz * (2 * zz - 1) < 1e12; ++zz) 
        ls[zz] = zz * (2 * zz - 1);
  
    int q;
    cin >> q;
  
    while (q--) {
        cin >> step;
        layer = lower_bound(ls, ls + zz, step) - ls; // 二分查找所在层数
        step -= ls[layer];

        x = layer - 1;
        if (layer & 1) x = -x;

        step = abs(step);
        if (step < layer) y = step;
        else if (step <= 3 * layer - 3) {
            y = abs(x);
            step -= y;
            if (x < 0) x += step;
            else x -= step;
        }
        else {
            x = -x;
            y = layer - (step - (3 * layer - 3) + 1);
        }

        cout << x << ' ' << y << endl;
    }
  
    return 0;
}
最后修改:2024 年 12 月 09 日
如果觉得我的文章对你有用,请随意赞赏