泰山挑夫2 解题报告 我能说脏话嘛!又被字符串读入给坑了

来源:互联网 发布:淘宝新号多少钱一个 编辑:程序博客网 时间:2024/05/02 02:26

这次做题,有了上一次被坑的经历,我淡定多了,虽然开始好题好久我才开始正式做题,而且加上第一题签到题我死活没读懂题意,在这种状态下我仍然坚持一遍遍的读,终于AC了;而且自己出数据1A掉他了,虽然基本还是在里面垫底,但是A掉他之后心情大好,之后读了两个题没太懂,没思路,之后又去做G,竟然FL,生平第一次啊!  心情大好的情况下,又开了一个题,题意依然不懂,读了一遍又一遍,看到好多人都A掉他了,我有耐心读,不断告诉自己一定不难,终于,读懂之后很快A掉了; 在之后的F题WA了两次,这个题有两个坑,第一次以为只有一个,提交WA了之后以为这个坑是我想多了,有WA了之后才发现,是我想少了……  经过修改终于搞定了…… 当然仍然是水题……


A题:

1-n个人围成一圈,中间有人有m个chip,轮流发,编号为i的人获得i块,剩下的不够分的就是自己的……

当时这句话仍是没看明白,郁闷啊!   The walrus number i gets i chips. 

B题是给以个二进制的数,位数不超过10^6   its digits does not exceed 106    

是偶数就/2 ,计数就加1,知道最后得到1,问需要多少步?       直接想想做就好,加1需要进位,但可以先不处理进位,把1当0使也行,(因为二进制最后一位是0才是偶数),碰到0再变为1,就相当于把进位处理完了……      最高位顶多产生1位进位……  仔细想想就好了!  本来不难的题,我怕出错又处理了前导零,但仍然出错,出现各种奇葩的错误,RE,郁闷啊,以为数组开小了,后来各种尝试都失败了,怎么办呢?   赛后开CF的数据,在本地机上自己测试,也没问题啊,   后来改进数据读入方式,从getline()读字符串,到gets读字符数组,后来又用scanf读字符数组,终于A掉了,这个时候我真想说脏话!  要不是看数据量太大,100W的不敢用cin能出错吗!   赛后测试cin也对!  c语言处理字符串伤不起啊!!!!   另附上一篇关于c,c++关于字符串处理的博文 C++ string 用法详解


C题没读,先不讨论,读题太慢,确实伤不起啊,人家A的比我多,读的也比我多啊!

C - Newspaper Headline

给两个串,s1,s2用尽可能少的s1凑成s2;  s1的字母顺序不能颠倒,如果和s2不能匹配上即擦掉这个字母,当然产生的空格的话不用管它,当他不存在就好……

我想了想,这个题如果不考虑时间效率的话只要同时扫s1,s2就可以了,相同指针都往前走,不同只把s1的指针往前走,直到走到结尾再从新开始(计数变量加1,表示用了一个s1),如果对s1扫一遍s2的指针不走,那么就说明不能匹配了,输出-1;

但是时间效率太低了,超时,怎么办呢?   一般碰到字母的题,字母只有26个,那就好优化啊给每个字母记录一个地址,如果同一个字母有多个的话直接方法vector里面,然后二分查找上一个字母匹配位置之后紧挨着的那个就好了……

vector我用的不熟,下面贴上sumy的代码:

#include <iostream>#include <cstring>#include <algorithm>#include <cstdio>#include <cmath>#include <vector>using namespace std;char s1[10005];char s2[1000005];int len1,len2;vector<int>Q[50];long long ans;int flag;int now;int main(){    ans=0;    flag=0;    for(int i='a';i<='z';i++)    {        Q[i-'a'].clear();    }    scanf("%s",s1);    scanf("%s",s2);    len1=strlen(s1);    len2=strlen(s2);    for(int i=0;i<len1;i++)    {        Q[s1[i]-'a'].push_back(i);    }    now=-1;    for(int i=0;i<len2;i++)    {///搜不到或者搜完结束        if(Q[s2[i]-'a'].size()==0)        {///表明没有对应的元素            flag=1;            break;        }        vector<int>::iterator pos=upper_bound(Q[s2[i]-'a'].begin(),Q[s2[i]-'a'].end(),now);        if(pos==Q[s2[i]-'a'].end())        {            ans++;            now=-1;            pos=upper_bound(Q[s2[i]-'a'].begin(),Q[s2[i]-'a'].end(),now);        }        now=*pos;    }    if(flag) cout<<"-1"<<endl;    else cout<<ans+1<<endl;    return 0;}



D - Queue

给10W个数,求每个数前面理他最远的比他小的数和她之间有多少个数,没有的话输出-1

最朴素的做法是O(n*n)的,铁定超时,当时还没想到好的优化方法,自己这类题做得太少了,一碰到现想几乎没有时间!


E - Ski Base

n个点,m条边,每加一条边,问当前图中有多少个不同的环。 

没读到这个题,读到也可能吓住了,其实是用并查集维护,另外再加上数学结论就好

代码超短!

题目大意,给你N个点,m条边,顺序去修这m条边,每修完一条边就计算滑雪场的数量,滑雪场是包含一条或者多条track(轨迹),每个track之间不必相连;  就是两个三角形可以算作是哪个不同滑雪场!         两个滑雪场认为是不同的如果含有不同的边!    每个track能走完所有的边不重复!   也就是说环 , 按照正常题意的理解:一个三角形外加多出来一条边顶多算一个滑雪场!   多出来的那一边边压根就不计算在内……   否则作为一个CF题,题意就太麻烦了!   根据正常提议的理解!   然后开始做题,分析题目知道,新加的边对滑雪场数目的影响肯定和原先的状态有关,所以类似于递推或者DP,或者找规律!     

当然实际最后这个题还是找规律找出来的,新加的边所连接的两点若果本来就在一个集合里面,那当前的数目就等于之前的数目*2+1  

理解题意是关键,四个小时的比赛,不可能只出几个水题,大多数题目出不出来的原因就是英语阅读能力差,然后即使单词认识但是对题目的理解不到位!   所以加强英语阅读能力外加正确把握题目意思很关键,前者是靠英语能力的提高,后者是靠多做题积累经验!!!!!


F - Restoring Password

给你一串80个字符啊密文0,1构成;然后给你10个10个01组成的串,表示从0--9;然后将密文翻译成原文,这样就相当于破解得到password,读题读了N遍才看懂啊,郁闷……  又是水题,看懂了之后直接1A



G - Friends

这是我FL的题,当时心情大好!  就是题意难懂,给5个人,m个关系;看这个样子能否把一个数学结论推翻,如果存在3个两两成对的关系,彼此不认识或者都认识那就可以,反之不行, 三个for嵌套,枚举三个人判断状态就好,此题也是阅读理解题啊,读懂就A


H - Frames

桌面上有多个文件,选中并删除他,问最少选中几次,每次只能选中矩形的形状;

当然可以横着选,也可以竖着选,最后一行如果补不齐的话也可以选中空白的地方,这样就不会造成多选的情况,分情况讨论即可,注意明确思路,这个题当初想到一个坑,WA了,以为自己想多了,又改回没有坑,又WA了,这才想明白有两个坑,不过也算错的比较少的了




原创粉丝点击