#2018.05.31再次考试

又是一场考试。

愉快地,今天又考了一次。这次的题目涉及到了线段树的维护,以及于字符串相关的LCS,但其实上只是在模板题的基础上提升了那么一点点。

这次考试使得rateing直接下了1500,主要原因是各种该拿的分全没拿住,计算了一下,如果T3T6的两道暴力没有出那样愚蠢的低级错误的话,是至少能拿60分的,T5开个long long 也能再拿14。如果觉得降人品没事的话T4输出个-1也能上个10来分,那么就排到比较前面的位置了。

(好了啦,别太难过了)主要分析一下这次考试的得失。

首先是,其实失去的只是一些分数。任何小错误都会使你全局崩盘,你会发现本和你相差不多的人却跑在了你前面,而能和同等的人拉开差距的地方就是所谓的小细节。排名最靠前的几位神的小失误使其只是跑了一两个点,那是他们实力所在。而越是像我这样的沙茶,越是要注重这种细节,自己也看到了,只是改几个花费不到1分钟的细节就能往前进个15名,而你自己没有把握这些点。

  1. 换行,T3的样例中 -1的情况是最后一组数据提供的,使我没有意识到自己的代码输出-1却没有换行。这完全属于自己把自己弄残。

  2. Int→long long 要记住,Dev里有个操作,可以把指定的在语句中出现的代码进行转换,一定要记住,打暴力的时候用上它,把int 全改为long long。或者,细心一点不要随手打int,留心换成long long。万不要在明明意识到的情况下却将几个int忘了。

  3. 特判你瞎改什么特判呢你瞎改什么特判呢。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中选择一个数xB中选择一个数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<
其实仔细一想这道题处理并不困难,只是这样的优化不易想到。
当然,我们也可以选择在找到 gcd 后,直接 O(n) 循环一遍,找出 A 数组中,是 gcd 倍数的最大的数; B 数组类似;
考试的时候当然是交了暴力,然后背走24分。

T3都是泪啊,,,我的五十分啊,,,题面还是像上次考试那样的皮。。

题目描述

         蓝月商场有n件宝贝,每件宝贝有两个属性:价钱price和品牌brand。其中brand1-5之间某个整数。每件宝贝价钱两两不同。

         贪玩蓝月有Q个代言人,每个代言人拍完戏之后,希望能从蓝月商场免费顺走一样宝贝。但是每个代言人有自己的喜好,例如古天乐只喜欢品牌1,陈小春喜欢品牌1或品牌2,渣渣辉喜欢品牌35……具体来说,代言人会有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^510^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次操作,有三种类型:

  1. 给出l,r,将区间[l,r]的Ai都加一。

  2. 给出l,r,询问区间[l,r]的Ai!的和,对10^9取模。

  3. 给出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如下

二进制操作数组

 #2018.05.31再次考试_第1张图片




 


         数据范围

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就有40int0

我就是爆0的那一堆。

2进制的操作尚不熟悉,且除了种一棵没有作用的树貌似就不会了。我果断选择了暴力,做到这里时间本来就不多了,于是就想着拿点部分分,全部加起来不会太难看(妄想)

然后分数就真的很难看了。。

这次考试收获还是挺丰盛的。也许在时间的分配上,在考试时做题的技巧,都会得到提升(吧?)想说的是,对知识的掌握太不牢固了,集训的进度太快,比较慢热的我难以接受,这几天脖子居然开始有点酸痛,果然还是缺乏锻炼啊。(抽自习课练舞的那时候感觉学习更高效些,或许这就是为什么人必须有必要的运动时间吧?)哎,提高效率提高效率,说起来容易做起来难。还是巩固知识优先,从最基本的复习起。

虽然岳神说得很委婉,考不好也是一种经验的积累,可考不好就是考不好,说明你的能力还不够,必须更用功,否则接下来积累的就不是经验而是被淘汰的可能了。

然力足以至焉,於人为可讥,而在己为有悔

 

你可能感兴趣的:(考试)