A:
题目的意思是总共有n个人订阅了频道,只要在线就一定读到了文章, 基于当前已有的人数a,有p条通知,每一条都是关于当前人数变化的,但是不知道具体是当前人数中的哪一个人离开或者哪一个人上线,在此等条件下,判断是否能确定所有人都已经读了文章,若能确定都读了文章,输出YES, 若能确定有人没读文章,输出NO, 否则不确定的话输出MAYBE
对于能否判断所有人是否已经读完了文章,可以通过累计在线人数和实际在线人数进行判读,在接收人员变动通知时,实际上就可以判断出所有人都读完文章的情况,因为若所有人都读完了文章的话,那么在某一个时刻,也就是能判断读完文章的那一刻,所有人一定同时在线,只有在这种情况下才能一定保证所有人都读完了文章,因为我们不知道人员变动是具体发生在哪一个人身上。
而对于一定能判断所有人中存在没读文章的情况和不确定是否全部读完的情况只有将所有的人员变动通知读完后才能判断,若累计的人员上线率(也就是只算上线,不算下线的情况)小于总人数,就一定能判断存在有人没读完,因为我按最好的情况判断这些上线的人全都是之前没有出现过的,由于它小于总人数,因此说明仍然有人没读,最好的情况都能确定是没读完,那么其余情况就一定能判断有人没读文章,而剩下的就是不能判断的情况,因为它累计的人数大于等于总人数,但是又不能确保那些上线的人都是之前没有上线过的,因此就不能判断是否存在没读完的人
#include<iostream>
#include<string>
using namespace std;
int t;
void solve()
{
int n, p, a;
string st = "";
cin >> n >> a >> p;
cin >> st;
if (a == n)
{
cout << "YES" << endl;
return;
}
bool sign = false;
int sum = a;
for (int i = 0; i < p; i++)
{
a += (st[i] == '+' ? 1 : -1);
sum += (st[i] == '+' ? 1 : 0);
if (a == n)
{
cout << "YES" << endl;
return;
}
}
if (sum < n)
{
cout << "NO" << endl;
return;
}
else cout << "MAYBE" << endl;
return;
}
int main()
{
ios::sync_with_stdio(false);
cin >> t;
while (t--)
solve();
return 0;
}
B:
给出一段由1~n组成的序列,通过某种排序将该序列转换成自然数的排列顺序,而排序方式是在2~n - 1中选一个数,将该数作为分界点,小于该数的放在左侧,大于等于该数的放在右侧组成新的序列,因此对于每一个逆序的两个数都要用一次排序才能够,例如 5, 3就要选择3或4或5中的任意一个数将这两个数进行排序
因此我们可以将当前数组排好序,并将它们在原数组中的序列记录下来,要达到题目要求,即对应数组元素和下标按从小到大递增,因为当前下标表示的是未经过排序的数组顺序,而在对下标排序的过程也就是对数组元素排序的过程,此时就将问题转化为了如何将数组下标排好序
再对下标进行遍历,若相邻两个下标,当前一个大于后一个说明当前下标对应的元素所在位置在后一个下标对应元素的后面,但是元素此时我们是按照正确顺序排的,说明这两个元素之间要进行排序,因此操作数加一
#include<iostream>
#include<string>
#include<vector>
using namespace std;
int t;
void solve()
{
int n;
cin >> n;
vector<int> a(n);
for (int i = 0; i < n; i++)
{
int x;
cin >> x;
a[x - 1] = i;
}
int ans = 0;
for (int i = 1; i < n; i++)
ans += (a[i - 1] > a[i]);
cout << ans << endl;
}
int main()
{
ios::sync_with_stdio(false);
cin >> t;
while (t--)
solve();
return 0;
}