又是一场考试。
愉快地,今天又考了一次。这次的题目涉及到了线段树的维护,以及于字符串相关的LCS,但其实上只是在模板题的基础上提升了那么一点点。
这次考试使得rateing直接下了1500,主要原因是各种该拿的分全没拿住,计算了一下,如果T3和T6的两道暴力没有出那样愚蠢的低级错误的话,是至少能拿60分的,T5开个long long 也能再拿14。如果觉得降人品没事的话T4输出个-1也能上个10来分,那么就排到比较前面的位置了。
(好了啦,别太难过了)主要分析一下这次考试的得失。
首先是”失”,其实失去的只是一些分数。任何小错误都会使你全局崩盘,你会发现本和你相差不多的人却跑在了你前面,而能和同等的人拉开差距的地方就是所谓的小细节。排名最靠前的几位神的小失误使其只是跑了一两个点,那是他们实力所在。而越是像我这样的沙茶,越是要注重这种细节,自己也看到了,只是改几个花费不到1分钟的细节就能往前进个15名,而你自己没有把握这些点。
换行,T3的样例中 -1的情况是最后一组数据提供的,使我没有意识到自己的代码输出-1却没有换行。这完全属于自己把自己弄残。
Int→long long 要记住,Dev里有个操作,可以把指定的在语句中出现的代码进行转换,一定要记住,打暴力的时候用上它,把int 全改为long long。或者,细心一点不要随手打int,留心换成long long。万不要在明明意识到的情况下却将几个int忘了。
特判你瞎改什么特判呢你瞎改什么特判呢。T1根本就不会无解,由于输入的数据x<=999998,而999999就是一个满足要求的数字,你封啥顶呢你封啥顶呢,特判的修改千万要注意题意,别自以为加了特判完善了代码结果一失足便是千古恨。
这是今天”得”的一些在今后写代码千万要注意的地方。
低分不是坏事,重点是能否把握低分带来的收获。
T1在考试时其实很快就写出来了。
题目描述
定义一个6位数是lucky的,当且仅当它的前3位之和等于后3位之和,比如165912
给出数x,找出最小的、大于x的幸运数字。
无解输出-1.
格式
输入:一个数,表示x
输出:一个数,表示下一个幸运数字
范围:
x=read();
for(int i=x+1;i<=999998;++i)
{
int num1,num2,num3,num4,num5,num6;
num1=i%10;
num2=(i%100-num1)/10;
num3=(i%1000-num2*10-num1)/100;
int le=num1+num2+num3;
num4=(i%10000-num3*100-num2*10-num1)/1000;
num5=(i%100000-num4*1000-num3*100-num2*10-num1)/10000;
num6=(i/100000);
int ri=num4+num5+num6;
if(le==ri)
{
cout<
T2是一道好题啊,是道非常优秀的题目。
好大的Gcd(gcd.cpp)
题目描述
有两个数组A,B,大小均为N。请在A中选择一个数x,B中选择一个数y,使得gcd(x,y)最大;如果有多组数gcd相同,找出x+y最大的。
格式
输入:第一行一个数n,第二行n个数表示Ai,第三行n个数表示Bi。
输出:输出gcd最大的那对数(gcd相同则和最大)的x+y的值。
范围
Sample Input 0
5
3 1 4 2 8
5 2 12 8 3
Sample Output 0
16
这题有点难,据老师说,由于这题的题面比较短,所以放在了这前面。
首先想到的肯定是暴力枚举,而我们的时间复杂度达到了优秀的O(N^2log n)就是直接套欧几里得公式求Gcd。
#include
using namespace std;
inline int read()
{
int s=0;
char c=' ';
bool whs=1;
for(;c>'9'||c<'0';c=getchar()) if(c=='-') whs=false;
for(;c>='0'&&c<='9';s=s*10-48+c,c=getchar());
return whs?s:-s;
}
const int N=1e6+10;
int n,a[N],b[N];
int maxa[N],maxb[N],cnt[N]={};//表示a[]数组中i的倍数的最大值
int main()
{
n=read();
for(int i=1;i<=n;++i) a[i]=read();//读入a数组
for(int i=1;i<=n;++i) b[i]=read();//读入b数组
for(int i=1;i<=n;++i) cnt[a[i]]++;//统计a[]中同一个数出现的次数
for(int i=1;i<=N;++i)
for(int j=i;j<=N;j+=i)//枚举倍数 如果倍数j存在
if(cnt[j]) maxa[i]=max(maxa[i],j);
for(int i=1;i<=n;++i) cnt[a[i]]=0;
for(int i=1;i<=n;++i) cnt[b[i]]++;//统计b[]中同一个数出现的次数
for(int i=1;i<=N;++i)
for(int j=i;j<=N;j+=i)
if(cnt[j]) maxb[i]=max(maxb[i],j);
int eq=0;
for(int i=1;i<=N;++i) if((maxa[i]!=0)&&(maxb[i]!=0)) eq=i;//如果i同时是A中某个数与B中某个数的因子。
cout<
T3都是泪啊,,,我的五十分啊,,,题面还是像上次考试那样的皮。。
题目描述
蓝月商场有n件宝贝,每件宝贝有两个属性:价钱price和品牌brand。其中brand是1-5之间某个整数。每件宝贝价钱两两不同。
贪玩蓝月有Q个代言人,每个代言人拍完戏之后,希望能从蓝月商场免费顺走一样宝贝。但是每个代言人有自己的喜好,例如古天乐只喜欢品牌1,陈小春喜欢品牌1或品牌2,渣渣辉喜欢品牌3和5……具体来说,代言人会有d个喜欢的品牌(1 <= d <= 5),同时他最喜欢这些品牌中,价钱第k便宜的宝贝。
请你求出每个代言人最喜欢的宝贝的价钱是多少!如果不存在这件宝贝,请输出-1.
格式
输入:第一行一个整数n,第二行n个整数描述每件宝贝的品牌,第三行n个数描述每件宝贝的价钱。第四行一个整数Q,接下来Q*3行,每3行描述一个代言人的信息。其中第一行一个整数d,第二行d个数表示喜欢的品牌,第三行一个数表示k。
输出:一共Q行,每行一个数。
范围:
Sample Input 0
3
1 1 2
1 3 2
3
1
1
2
2
1 2
2
1
3
1
Sample Output 0
3
2
-1
Ps:这里无心侵犯游戏版权,据老师所言我们已经获得相关开发商的允许,若有疑问者可以联系我们的老师。
好了,这里看到数据10^5与10^5,显然暴力是过不了的,但上下思索我似乎只能写暴力。然而就是这份暴力枚举,断送了我平rateing的想法。。我的printf没有带上\n。
好了就这样接下来是正解。
这道题的方法其实很多变,刚讲完的状压可以在这里派上用场。效率应该是O(2^m n log n + m)的,然而我并写不出来。
再来是二分答案,这个本来有想过但不知如何实现(代码力不足),由于我们需要的是第k便宜的宝贝,这可以用二分进行查找,
#include
using namespace std;
int n,q;
struct goods
{
int pri;
int bra;
} s[100100]={};
int c[500100],s1[500100],s2[500100],s3[500100],s4[500100],s5[500100];
int d,m,k;
inline int read()
{
int s=0;
bool whs=1;
char c=' ';
for(;c>'9'||c<'0';c=getchar()) if(c=='-') whs=false;
for(;c>='0'&&c<='9';s=s*10-48+c,c=getchar());
return whs?s:-s;
}
int mycmp(goods x,goods y)
{
return (x.pri=k) r=mid-1;//向左找
else l=mid+1;//向右找
}
cout<
接下来的T4。
有愧于语文老师,我看不懂题目。。。我认认真真看了我只知道条件达不到的情况下输出-1而我不明白为什么会达不到条件……..这里需要用到LCS,而我全脸懵逼。。
T5,
题目描述
给出长度为n的序列A1,A2,…,An。进行m次操作,有三种类型:
给出l,r,将区间[l,r]的Ai都加一。
给出l,r,询问区间[l,r]的Ai!的和,对10^9取模。
给出I,v,将Ai单点修改为v。
格式
输入第一行两个数n,m,第二行n个数Ai。
接下来m行,每行三个数,第一个数k,表示第几类操作,后面两个数如题所述。
输出:对于每个操作2输出解。
范围
Sample Input 0
5 7
1 1 1 1 1
2 1 5
1 1 5
2 1 5
1 1 3
2 1 5
3 1 15
2 1 5
Sample Output 0
5
10
22
674368016
看完题目第一眼就是用线段树来维护,包括下面的一道题目,于是我开始最基本的线段树的操作,当我写到70多行的时候,想想,不对啊,这样写下去会崩。因为这里的查询查询的是区间的阶乘的累加和,阶乘,随便一个二位数的阶乘就能爆int。对10^9取模,这需要对每一片叶子做预处理,每一片叶子维护这个点的阶乘。
但是,,但是,,但是这样的操作我无法在短时间内实现,只是模板就敲得头疼。
于是我选择打了暴力,想着能捞点分吧,结果少改了一个longlong。
于是又丢了12分啊(就是这么愉快而轻松)
我们发现 如果x>=40,我们x的阶乘去mod 1e9时答案为0
所以我们只需要考虑小于40的所有数,用线段树来维护这些树就可以了(我当然是选择口胡过去)
由于每个数最多被修改40次,所以我们总共的时间复杂度为O((n+q)*50*log n);
代码实现交给未来的我????
T6如下
二进制操作数组
数据范围
Sample Input 0
6 6
8 9 1 13 9 3
1 4 5
2 6 9
1 3 7
2 7 7
1 6 1
2 11 13
Sample Output 0
45
19
21
这道题的暴力其实给分是很足的 然而开了long long就有40开int爆0。
我就是爆0的那一堆。
对2进制的操作尚不熟悉,且除了种一棵没有作用的树貌似就不会了。我果断选择了暴力,做到这里时间本来就不多了,于是就想着拿点部分分,全部加起来不会太难看(妄想)
然后分数就真的很难看了。。
这次考试收获还是挺丰盛的。也许在时间的分配上,在考试时做题的技巧,都会得到提升(吧?)想说的是,对知识的掌握太不牢固了,集训的进度太快,比较慢热的我难以接受,这几天脖子居然开始有点酸痛,果然还是缺乏锻炼啊。(抽自习课练舞的那时候感觉学习更高效些,或许这就是为什么人必须有必要的运动时间吧?)哎,提高效率提高效率,说起来容易做起来难。还是巩固知识优先,从最基本的复习起。
虽然岳神说得很委婉,考不好也是一种经验的积累,可考不好就是考不好,说明你的能力还不够,必须更用功,否则接下来积累的就不是经验而是被淘汰的可能了。
然力足以至焉,於人为可讥,而在己为有悔