2020牛客暑期多校训练营(第三场)
就写一下自己写了的题,也不好意思发去要牛币了
A,Clam and Fish
题意大概就是现在有一个人在捞鱼,河里有四种状态,有鱼有诱饵,有鱼无诱饵,无鱼有诱饵,无鱼无诱饵,四种状态每次可以操作一次在有鱼的状态下可以拿鱼,在有诱饵的状态下可以拿诱饵,如果在无鱼但是之前拿了诱饵也可以消耗一个诱饵拿鱼,(只能选择拿鱼或者拿诱饵或者什么都不做三个中的一个),现在给你一个序列由0123组成分别表示四个状态,问你能拿到最多的鱼数量,既然要拿鱼最多那么我们在有鱼的时候就选择拿鱼,毕竟拿了诱饵还要下一次才能换成鱼,所以在有鱼的状态下肯定是拿鱼,那么我们要考虑的就是在01(0表示两个都没有,1表示有诱饵)两种的时候贪心,这里考虑到一个问题,拿了诱饵要能用出去,我的想法就是直接倒过来,用一个cnt表示现在的空地数(表示能用诱饵的地方),遇到一个1就看看cnt是否大于0,大于0就选择拿诱饵,这样就可以空地数减一,即cnt--,sum++,
代码
#include <cctype> #include <cfloat> #include <cmath> #include <cstdio> #include <cstdlib> #include <cstring> #include <ctime> #include <algorithm> #include <deque> #include <fstream> #include <functional> #include <iomanip> #include <iostream> #include <istream> #include <iterator> #include <list> #include <map> #include <ostream> #include <queue> #include <set> #include <sstream> #include <stack> #include <string> #include <utility> #include <vector> #include <unordered_map> #include <unordered_set> #define ll long long using namespace std; const ll MAXN=2e6+10; char s[MAXN]; int main(void){ int T; scanf("%d",&T); while(T--){ int n; int sum=0; int cnt=0; scanf("%d",&n); scanf("%s",s); for(int i=n-1;i>=0;--i){ if(s[i]=='2'||s[i]=='3') sum++; else{ if(cnt==0&&s[i]=='1'||s[i]=='0') cnt++; else if(cnt!=0) sum++,cnt--; } } printf("%d\n",sum); } return 0; }
B,Classical String Problem
这个题目的意思很简单,给出一个字符串,然后给两个操作A b表示输出第b个数字,M b表示移动字符,如果b是正数,比如2表示把最左边的两个字母移到最右边,如果是负数,比如-2就是将最右边的两个字母移到最左边。本来一开始我是直接构建字符串,每移到一次就构建一个新的字符串代替原来的,但是超时了。。。。所以我们只能考虑指针的移动,这里的指针移动和循环队列很相似可以把他看成一个循环队列来做,设置一个头指针,本来我还设立尾指针,但是其实用不到,因为这里没有加减字符串的操作,这个题目其实我也是一边写代码一边才看懂这个指针怎么移动的,用题目中的样例nowcoder,我们执行M 2,就得到wcoderno是不是就像是头指针向左移了两个单位,现在头指针指向-2+8=6,然后我们按照6为头指针向右边走是不是还是原来那个字符串,这样一看是不是就理解了,同理-2就是头指针右移两个单位,现在只要对指针好好处理就没事了。
说实话这个题目我一开始不知道要怎么给字符串多组输入,一开始我用的是string类,我只知道用while(cin>>s)然后就超时,主要是一开始总不记得要吸收回车,导致后面读入AB的时候出现问题,然后就是牛客上面不用多组也行。。。。。
#include <cctype> #include <cfloat> #include <cmath> #include <cstdio> #include <cstdlib> #include <cstring> #include <ctime> #include <algorithm> #include <deque> #include <fstream> #include <functional> #include <iomanip> #include <iostream> #include <istream> #include <iterator> #include <list> #include <map> #include <ostream> #include <queue> #include <set> #include <sstream> #include <stack> #include <string> #include <utility> #include <vector> #include <unordered_map> #include <unordered_set> #define ll long long using namespace std; const ll MAXN=2e6+5; char s[MAXN]; int main(void){ scanf("%s", s); int n,b,len = strlen(s); char a; int front=0,rear=len-1; scanf("%d",&n); while(n--){ getchar(); scanf("%c%d",&a,&b); if(a=='A'){ if(front+b-1>=len){ printf("%c\n",s[front+b-1-len]); } else{ printf("%c\n",s[front+b-1]); } } else{ if(b>0){ front+=b; if(front>=len){ front-=len; } } else{ front+=b; if(front<0){ front+=len; } } } } return 0; }
L,Problem L is the Only Lovely Problem
这个题目是签到题,就是输入一串字符,如果这串字符的开头是lovely就输出lovely,否则输出ugly,这个题目唯一的难点就是判断开头是否为lovely不区分大小写,所以我们把开头那一段全部化成大写或者小写就可以了,这个题目用py很容易,因为有直接转换的函数,但是我还没学到那里,所以我还是用c++手写了一个转换的,因为只需要比较开头,所以我用一个新的字符串装下原来的那个字符串开头的6个字符再全部转化为小写,虽然繁杂了一点但是节约了一点运行时间代码
#include <cctype> #include <cfloat> #include <cmath> #include <cstdio> #include <cstdlib> #include <cstring> #include <ctime> #include <algorithm> #include <deque> #include <fstream> #include <functional> #include <iomanip> #include <iostream> #include <istream> #include <iterator> #include <list> #include <map> #include <ostream> #include <queue> #include <set> #include <sstream> #include <stack> #include <string> #include <utility> #include <vector> #include <unordered_map> #include <unordered_set> #define ll long long using namespace std; int main(void){ string a1="lovely"; string n,n1; while(cin>>n){ n1.assign(n, 0, 6); for(int i=0;i<n1.length();++i){ if(n1[i]<='Z') n1[i]+=32; } if(n1==a1) cout<<"lovely"<<endl; else{ cout<<"ugly"<<endl; } } }