A.手机桌面
З手机桌面- A - Codeforceshttps://codeforces.com/contest/1974/problem/A
解析题目
这个问题是一个应用图标布局的最优化问题,主要是要最小化使用的桌面屏幕数量。每个屏幕是5行3列的网格,共有15个单元格。我们有两种图标:1x1大小的图标和2x2大小的图标。题目要求得出放置x块1×1和y块2×2的最少屏幕个数。
分析思路
我们首先可以考虑2×2的方块,显然,一个屏幕只能放得下2个2×2的图标,如上图所示
但是 我们又可以在一个屏幕布满2×2的图标中放置1×1的图标。所以我们可以优先考虑2×2的情况
然后根据屏幕中剩余的空间来分配1×1的图标,如果x是大于剩余空间的,那么我们就需要新增屏幕的个数来装下多余的图标
这里有个向上取整的小技巧,通常使用 被除数 + (除数 - 1)/ 除数
对于2×2的图标
- 目标:确保在计算放置2x2图标所需屏幕数时,所有图标都能被包含。由于每个屏幕可以放置最多两个2x2图标,当有奇数个2x2图标时,单纯的除法会向下取整,可能导致计算出的屏幕数不足
- 方法:加1是在这种情况下最简单的修正方法。对于每2个图标需要一个屏幕的计算,通过y+1可以确保当你有奇数个图标时,这个额外的图标也能得到计算。例如,对于5个2x2图标,
(5 + 1) / 2 = 3
正确反映了需要3个屏幕(而不是5 / 2 = 2.5
向下取整为2个屏幕)。
对于1×1的图标
- 目标:确保在计算额外需要多少屏幕来放置1x1图标时,每个屏幕的容量被最大化利用,且所有图标都能被放置。
- 方法:由于每个屏幕可以放置15个1x1图标,加14确保了在计算额外屏幕时,即使有1到14个多余的1x1图标,也会额外考虑一个屏幕。这避免了由于整数除法的向下取整而导致的屏幕数不足。例如,如果有16个1x1图标,
16 + 14 = 30
,然后30 / 15 = 2
正确计算出需要2个屏幕。
代码
#include <iostream>
using namespace std;
int main() {
int t;
cin >> t;
while (t--) {
int x, y;
cin >> x >> y;
// 计算至少需要多少屏幕来放置所有2x2图标,向上取整
int screens_for_2x2 = (y + 1) / 2; // 每个屏幕最多放2个2x2图标
// 计算当前屏幕中剩余的单元格数
int remaining = 15 * screens_for_2x2 - 4 * y;
//cout<<remaining<<'\n';
// 判断1x1图标是否可以完全放入剩余的空间
if (x > remaining) {
x -= remaining; // 移除已占用的空间
// 新屏幕需要为剩下的1x1图标提供空间
int additional_screens = (x + 14) / 15; // 每个屏幕可以放15个1x1图标,保证向上取整
//cout<<additional_screens<<'\n';
screens_for_2x2 += additional_screens;
}
// 输出每个测试案例所需的最小屏幕数
cout << screens_for_2x2 << endl;
}
return 0;
}
B. 对称编码
任务 - B - Codeforceshttps://codeforces.com/contest/1974/problem/B
解析题目
题目的意思是给你一个对原始字符编码的结果的字符串s,要求你通过对称方式来获得原始字符串s
分析思路
既然题目有了对原字符串编码后的字符串b,那么我们需要通过构造一个辅助字符串r来把字符串b中每个字符换成字符串r中的对称字符,从而得到原始字符串s。对称关系如图所示:
首先就是构造辅助字符串r
题目中对辅助字符串r是这样描述的:它建立了一个新的助手线r,它由字符串的所有不同字母组成s按字母顺序书写;
那么我们就可以考虑用桶来记录每个字符出现的次数,只要出现过,就让他加在辅助字符串r中;
通过字符串r来找到对应的替换关系
构造一个字符数组用于解码
对称式的映射关系怎么表示呢?
我们知道的是,第一个要替换成倒数第一个,第二个要替换成倒数第二个。由此类推,我们会发现,位于字符串r中的第i个位置的字符串要替换成r_len-i-1位置的字符。那么我们通过这种规律来构造字符数组。
构造原始字符串s
我们通过上一步构造的字符数组来构造原始字符串s
例如:考虑b字符串当中的c字符,通过映射关系,字符数组里面储存的就是字符s,那么显然,只需要遍历字符串b,通过每一次访问当前字符串b中的字符对应的字符数组中的元素,来确定原始字符串的每一个字符。
代码
#include <bits/stdc++.h>
using namespace std;
int main() {
int t;
cin >> t;
while (t--) {
int n;
cin >> n;
string b;
cin >> b;
// 清零字符计数数组
vector<int> count(26, 0);
// 计数b中的字符
for (char ch : b) {
count[ch - 'a']++;
}
// 构建辅助字符串r
string r = "";
for (int i = 0; i < 26; i++) {
if (count[i] > 0) {
r += char(i + 'a');
}
}
// 创建一个字符数组用于解码
char decode[122];
int r_len = r.length();
for (int i = 0; i < r_len; i++) {
decode[r[i]] = r[r_len - i - 1];//让r[i]对应的解码是r的len - i -1位置处的字符
}
// 构造原始字符串s
string s = "";
for (char ch : b) {
s += decode[ch];
}
cout << s << endl;
}
return 0;
}