- 温张鑫 的博客
七月day13
- @ 2025-7-27 20:57:57
T1 蜡烛
题意:用最短时间点燃K支蜡烛。
思路:a[r] - 2 * a[l] 表示先从右走到最左边的蜡烛(距离为-a[l]),再向右走到最右边的蜡烛(距离为a[r] - a[l]),总距离为-a[l] + (a[r] - a[l]) = a[r] - 2 * a[l] -a[l] + 2 * a[r] 表示先向右走到最右边的蜡烛(距离为a[r]),再向左走到最左边的蜡烛(距离为a[r] - a[l]),总距离为a[r] + (a[r] - a[l]) = 2 * a[r] - a[l]。
代码:
#include<bits/stdc++.h>
using ll = long long;
using namespace std;
const int N = 1e5 + 10;
int a[N]; // 存储每个蜡烛的坐标
int n, k, ans = 0x3f3f3f3f; // n蜡烛总数,k连续糖果数,ans初始化求最小值
int main()
{
//文件读写
freopen("candy.in", "r", stdin);
freopen("candy.out", "w", stdout);
cin >> n >> k;
// 读取每个蜡烛的坐标
for (int i = 0; i < n; i++)
{
cin >> a[i];
}
// 枚举所有可能的连续k个蜡烛的区间
for (int i = 0; i <= n - k; i++)
{
int l = i; // 左端点
int r = i + k - 1; // 右端点
int t = 0; // 最小移动距离
// 情况1:如果区间内所有蜡烛坐标都非负数
// 最优路径是直接向右走到最右边的蜡烛,再返回原点
if (a[l] >= 0)
{
t = a[r]; // 总距离为最右边蜡烛的坐标值
}
// 情况2:如果区间内所有糖果坐标都为负数
// 最优路径是直接向左走到最左边的蜡烛,再返回原点
else if (a[r] <= 0)
{
t = -a[l]; // 总距离为最左边糖果坐标的绝对值
}
// 情况3:区间内同时包含正负两种坐标的蜡烛
else
{
// 需要考虑两种路径并取较小值:
// 1. 先向左走到最左边的蜡烛,再向右走到最右边的蜡烛
// 总距离 = 向左走的距离 + 向右走的距离 = (-a[l]) + (a[r] - a[l]) = a[r] - 2*a[l]
// 2. 先向右走到最右边的蜡烛,再向左走到最左边的蜡烛
// 总距离 = 向右走的距离 + 向左走的距离 = a[r] + (a[r] - a[l]) = 2*a[r] - a[l]
t = min(a[r] - 2 * a[l], 2 * a[r] - a[l]);
}
// 更新
ans = min(ans, t);
}
cout << ans; //输出
return 0;
}
T2 白日梦
题意:让字符串T中只包含字符串S中的四个单词,如果S = T,输出YES,否则输出NO。
思路:1:因为有些单词加起来会一样,为了避免出现这种情况,我们可以把单词反过来输出。
2:利用字符串末尾字符erase函数O(1)时间复杂度的性质,从末尾进行判定删除
代码:
#include<bits/stdc++.h>
using namespace std;
int main()
{
freopen("daydream.in","r",stdin);
freopen("daydream.out","w",stdout);
string s;
cin >> s; // 读取输入字符串
int n = s.length(); // 获取字符串长度
// 从后往前尝试分解字符串
while (n > 0)
{
// 如果剩余字符长度小于最短单词长度(5),无法继续进行
if (n < 5)
{
cout << "NO"; // 所以输出NO
return 0;
}
char c = s[n-1]; // 获取当前末尾字符
// 根据末尾字符选择单词
if (c == 'm')
{
// 尝试匹配"dream" (长度5)
if (n >= 5 && s.substr(n-5, 5) == "dream")
{
n -= 5; // 匹配成功,移除已经匹配的部分
}
else
{
cout << "NO"; // 无法匹配,输出NO
return 0;
}
}
else if (c == 'r')
{
// 优先尝试匹配更长的"dreamer" (长度7)
if (n >= 7 && s.substr(n-7, 7) == "dreamer")
{
n -= 7; // 匹配成功,移除已匹配的部分
}
// 其次尝试匹配"eraser" (长度6)
else if (n >= 6 && s.substr(n-6, 6) == "eraser")
{
n -= 6; // 匹配成功,移除已经匹配的部分
}
else
{
cout << "NO"; // 输出NO
return 0;
}
}
else if (c == 'e')
{
// 尝试匹配"erase" (长度5)
if (n >= 5 && s.substr(n-5, 5) == "erase")
{
n -= 5; // 匹配成功,移除已匹配部分
}
else
{
cout << "NO"; // 无法匹配,输出NO
return 0;
}
}
else
{
// 末尾字符为'a'或其他字符,无法组成目标单词
cout << "NO";
return 0;
}
}
// 运行完代码,输出YES
cout << "YES";
return 0;
}
T3 重复重复重复...重复重复
题意:找出满足条件的最大正整数。
思路:重复数公式:d*(-1)/9,枚举。
代码:
#include<bits/stdc++.h>
using ll = long long;
using namespace std;
const int N = 1e5+10;
int n, m;
int a[N];
int main()
{
freopen("repeat.in", "r", stdin);
freopen("repeat.out", "w", stdout);
cin >> n >> m;
a[1] = 1 % m;
for (int i = 2; i <= n; i++)
{
a[i] = (10 * a[i - 1] + 1) % m;
}
for (int i = n; i >= 1; i--)
{
if (a[i] == 0)
{
for (int j = 1; j <= i; j++)
{
cout << 9;
}
return 0;
}
for (int j = 9; j >= 1; j--)
{
if ((j * a[i]) % m == 0)
{
for (int k = 1; k <= i; k++)
{
cout << j;
}
return 0;
}
}
}
cout << -1;
return 0;
}