A - Deletions of Two Adjacent Letters
题意:给你一个字符串s,和字符c,你可以重复以下操作(也可以不操作):每次选择两个相邻的字母删除,问s是否可以通过上述操作变成c
思路:通过样例可以发现当c位于s中的奇数位置时,可以通过操作变成c,所以只需要看一下c在s中的位置并且特判一下s只有一个字符的情况即可
代码:
void solve()
{
string s;
cin >> s;
if (s.size() == 1)
{
string c;
cin >> c;
if (s == c)
cout << "YES" << endl;
else
cout << "NO" << endl;
}
else
{
s = " " + s;
bool flag = false;
char c;
cin >> c;
for (int i = 1; i < s.size(); i++)
if (s[i] == c && i % 2 == 1)
flag = true;
if (flag)
cout << "YES" << endl;
else
cout << "NO" << endl;
}
}
题意:给定一个函数f(x)=x/a+xmoda.其中a是给定的数,给出x可以取的范围为[l,r],求在这个范围内的最大f(x)的值
思路:这个题其实挺容易想到当模数为a-1时f(x)是取最大的,但是需要考虑特殊情况,如当l/a==r/a(并不是区间长度小于a),(因为在这个区间内f(x)的值是单调递增的),以及r%a==a-1的时候,其他情况都是r向前进1,再令模数为a-1
代码:
void solve()
{
int l, r, a;
cin >> l >> r >> a;
// 求x/a+x%a的最大值,就是找规律,如果区间长度小于a或者是r+1刚好整除a,说明r%a==a-1则r时取最大,其他情况都向前进1
int ans = 1;
if (l / a == r / a || r % a == a - 1)
ans = r / a + r % a;
else
ans = r / a - 1 + a - 1;
cout << ans << endl;
}
C - Weight of the System of Nested Segments
题意:给出一个嵌套段的定义(类似区间套),给出m个坐标以及对应的权值,要求恰好将这m个坐标分成n个嵌套段的的权值最小,同时输出权值最小的情况下各个段的两个端点的坐标
思路:通过样例解释可以看出一个段的权值,只算这个段的两个端点的权值,所以我们可以开一个结构体,记录每个点的坐标,对应的权值,以及读入的下标,然后先根据权值排序,再根据坐标排序。前2*n个坐标对应的权值就是这个最小段的权值,然后坐标的话直接按照第一个和最后一个形成一段,第二个和倒数第二个形成一段的方式,一段套一段的形式即可,再输出对应坐标
代码:
#define int long long
const int N = 2e5 + 10;
struct node // 先按照权值排再按照坐标排
{
int val; // 权值
int pos; // 坐标
int id; // 输入的顺序
} a[N];
bool cmp(node a, node b)
{
return a.val < b.val;
}
bool cmp1(node a, node b)
{
return a.pos < b.pos; // 位置从小到大
}
void solve()
{
int n, m; // 分成n块,m个坐标和其对应的权值
cin >> n >> m;
for (int i = 1; i <= m; i++)
cin >> a[i].pos >> a[i].val, a[i].id = i; // 记录输入顺序,后面输出的时候按照输入顺序输出
sort(a + 1, a + m + 1, cmp); // 先按照权值从小到大排
sort(a + 1, a + 2 * n + 1, cmp1);
int ans = 0;
for (int i = 1; i <= 2 * n; i++)
ans += a[i].val;
cout << ans << endl;
for (int i = 1; i <= n; i++)
cout << a[i].id << " " << a[2 * n - i + 1].id << endl;
cout << endl;
}