A - 分西瓜
判断奇偶性,需注意当给定整数为2时即使分成两组也是1和1不满足题意
B - 牛和扑克
不是‘F’的人伸手,但是剩余的人中不能含有对应的状态‘A’和 ‘I’,注意需要特判不相等的情况
C - ABBBBB
不难发现,我们可以删掉的字符串是 AB 以及 BB 他们结尾都是B,并且删除的都是上一个字符,所以我们采用栈来存储,当读入到B的时候移除栈顶元素,若栈内为空则入栈
D - 超级大跳
我们不难发现 对于每个位置 都先计算i + a[i] 然后判断 i + a[i] 与 n 的关系,若大于则停止,若小于则累计到下一位,所以不难写出公式,所以我们发现在后面的 dp 取决于前面的 dp值,所以从后向前考虑,不难思考出递推公式,其中dp[i] 是以i为起点的最大得分
E - 奇偶游戏
A,B两人进行游戏,都希望最大化两人的得分差距,两人操作逻辑相同,这里只列出A的操作逻辑,A如果执行拿取操作,则自己得分增加,若执行去除操作,则对方得分减少,故使用两个大根堆来实现,一个奇数大根堆一个偶数大根堆,拿取两个堆顶的较大值,从自己的大根堆内拿去就是加自己的分,拿对方的就是减对方的分,最后比较二人得分即可(也可以使用一个大根堆实现).
F - 跳跃
朴素思想是先按照1+2+3+...+i的方式走到大于等于n的位置,然后再往后倒退.但是存在先倒退到-1在前进的特殊情况,并且不难发现无论想负方向后退多少步再往前走都是到达相同的位置,故只考虑-1的情况,模拟,bfs,dp都可实现本题
G - 序列变化
对于 一个序列 1 2 3 2 1
我们只需要 判断 1 x x x 1 , x 2 x 2 x , x x 3 x x,中x的连续序列个数,例如 1 x x x 1中只有一段连续的x , x 2 x 2 x 中有三段 , 需要从各个序列中取得最小连续x个数即可,语言描述抽象,见代码
int a[N];
map<int,vector<int> > v;
int n;
int cal(vector<int> & tmp)
{
int len = tmp.size();
int cnt = 0;
for(int i = 0 ; i < len ; i ++)
{
if( i == 0 && tmp[i] != 1)
cnt ++;
if( i == len - 1 && tmp[i] != n)
cnt ++;
if( i > 0 && tmp[i] - tmp[i - 1] > 1)
cnt ++;
}
return cnt;
}
void Rainbow_()
{
cin >> n;
v.clear();
for(int i = 1; i <= n; i ++)
{
cin >> a[i];
v[ a[i] ].push_back(i);
}
int minn = INF;
for(auto tmp : v)
minn = min( minn , cal(tmp.second) );
cout << minn << '\n';
return ;
}