题目大意
一个游戏包含n个阶段,每个阶段有四种类型:
类型0:没有鱼也没有蛤。
类型1:只有一只蛤。
类型2:只有一条鱼。
类型0:没有鱼也没有蛤。
类型1:只有一只蛤。
类型2:只有一条鱼。
类型3:有一条鱼和一只蛤。
在每个阶段都可以执行四种操作之一:
1.用一只蛤换一包鱼饵。
2.如果有一条鱼,可以无需鱼饵抓到这条鱼。
3.无论在此阶段有没有鱼,都可以使用一包鱼饵捕获一条鱼。
4.跳过阶段。
要求求出每局游戏中能抓到鱼的最大条数。
给出样例数量(游戏次数)t (1≤t≤2.5×105)。每次游戏给出阶段数n(1≤n≤2×106)以及一个长度为n的字符串,s[i-1]为第i阶段的类型。n的总和不超过2×106。
解题思路
这里使用时间复杂度是O(n)的模拟。
首先考虑,在每个阶段所应该采取的操作。
显而易见,在类型3与4时,直接抓鱼永远是最佳选择。(直接白嫖永远第一)
但是在类型0时,只能通过鱼饵抓鱼;类型1时,可以换鱼饵或者用鱼饵抓鱼。
所以,我们先忽视前导0,在3或4时无脑在答案加1。
后面遇到一个0,就尽可能使用鱼饵;遇到1,就先默认制作鱼饵,将现在拥有的鱼饵数量加1。
最后如果有剩余鱼饵>=,则可以用2次类型1的多余阶段来再抓一条鱼(一次换鱼饵,一次抓鱼)。
AC代码
flag用来记录有没有遇到第一个类型1,flag==0时的0没有鱼饵,都要跳过。
#include<bits/stdc++.h> using namespace std; int t,n,x,i,j,tot; int main() { string s; scanf("%d",&t); while(t--) { scanf("%d",&n); cin>>s; tot=x=i=0; bool flag=0; while(s[i]=='0') i++; for(;i<n;i++) { if(s[i]=='2' || s[i]=='3') { tot++; continue; } if(flag==0 && s[i]=='1') flag=1; if(flag==1 && s[i]=='1') x++; if(flag==1 && s[i]=='0' && x) tot++,x--; } if(x>=2) tot+=x/2; printf("%d\n",tot); } return 0; }