2017.3.26考试

总述:

这次的考题很综合,并没有偏向数据结构也没有偏向某一种思维模式,主要是在题目的分析与解题思路的生成上,没有过多的以前的做题经验可以借鉴,就是对题的把控和时间的把握。

这次的考试,出现了一个很大的偏差,其实以前也是经常发生的,就是我对题意的理解有问题。

我有时候会很较真在某些并不太准确的表述上(或许是不符合我认为的严密的逻辑),然后从文字里挖出一堆漏洞来钻牛角尖,把一个简单题搞得特别的复杂,并且增加了很多不必要的限制,导致难度加大,然而我也并没有什么办法,大概还是见的题少了些,经验不太够。

说实话,即使是考完之后,我依然并不是很懂得第一题究竟是什么意思,于是导致我按照自己的理解把一道很简单的排序题写成了线段树。

第二题看到题目我感觉十分的开心,在确认题目描述后就肯定它是单调栈了,因为此类题目很久很久以前做过,而且由于当时拒绝用单调栈还绕了很大的弯子,因为会需要考虑很多种情况,所以给我留下了心理阴影,印象比较深。

第三题再次输在了题意的理解上(我以为只要两个点之间有一条路径就可以了,于是发现自己根本就不会,而且判断绝对超时,于是直接放弃了),但是这道题就不能完全怪题目描述了,本身也是怪自己概念定义根本记不清(比如这题的完全图)。我长期懒得去记忆一些东西,到最后堆积起来,看什么都觉得熟悉,又看什么都觉得不是很清楚(这种概念问题犹为突出地体现在我的物理化学上)。昨天下午和班主任在办公室聊了一节自习课,觉得他对我的分析很对,他说的也非常有道理,“既然付出了时间在这上面,那就一定要有回报,既然想好,那就一定要把所有的东西都弄清楚,模棱两可的,算不得八班人。”我觉得竞赛更应该是如此的,因为自己太懒又比较能辩的原因,我常常给自己找借口,事情喜欢拖沓,总想着等一会儿有时间了再做,于是很多的东西就这样被落下,竞赛中的很多细节我也并没有太在意,我承认我并没有全力以赴,无论是做什么都是如此,所以导致了现在这个好像会又好像不会的样子。应该把所有东西都弄清楚的,这很关键,也是基础。最后我这题直接输出了DA。

话说我在放弃了第三题后把剩下的所有时间全部放在了第四题,我当时有两个思路,都比较笨拙,一是线段树(后来被我否了,因为我觉得这个应该写不出来),二是平衡树,因为平衡树首先是作为一棵二叉排序树存在的,所以它在结构上就会具有一种向上更新区域某值的功能,可以维护一个性质的值,我又把询问的区间左端点排序,离散化然后按照区间大小往树里面塞元素,如果在不爆内存的情况下或许是可行的(应该可以拿一些分数),因为查询次数多的时候,区间就会比较小,所以我写了很久,然而,,可能是细节处理得不好,所以调试了很久,但是最后还是wa了。

题目:

问题 A(3346): 银行账户

时间限制: 1 Sec  内存限制: 256 MB  Special Judge

题目描述

大家都知道28定律吧,据说世界上20%的人拥有80%的财富。现在你对一家银行的账户进行检测,看是否符合28定律,或者有更强的定律。比如说,10%的人拥有85%的财富。更准确的描述是:对N个银行账户进行调查,你的任务是找出两个数A,B,使得B-A的差最大。AB的含义是A%的人拥有B%的财富。

输入

输入的第一行包含一个整数N(1<=N<=300000),表示银行账户的个数。

接下来一行包含N个整数,每个整数在区间[0,100000000],表示这N个账户中的存款金额。

输出

输出两行,分别是两个实数A,BA,B的含义如题所述。误差在0.01内可以接受

样例输入

2 100 200

样例输出

50.066.66666666666666

提示

B-A的差值是唯一的,但B和A可能有多重可能。你的答案中,如果B-A的差值与标准答案的B-A的差值相差为0.01以内,则认为正确。所以,本题是specail judge


对金额排序后最值将出现在两边,然后从大到小依次找财富的比率,O(NlogN+N)就可以了,注意浮点数误差
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<algorithm>
using namespace std;
const int Max=300000;
int N;
int D[Max+5];
double All,Ans;
void getint(int &num){
    char c;int flag=1;num=0;
    while((c=getchar())<'0'||c>'9')if(c=='-')flag=-1;
    while(c>='0'&&c<='9'){num=num*10+c-48;c=getchar();}
    num*=flag;
}
int main(){
	//freopen("account.in","r",stdin);
	//freopen("account.out","w",stdout);
	getint(N);
	for(int i=1; i<=N; ++i)
		getint(D[i]),All+=D[i];
	sort(D+1,D+1+N);
	double A,B,la,now=0.0;
	for(int i=N; i; --i){
		la=(N-i+1)*1.0/N;
		now+=D[i];
		if(now/All-la>Ans)
			Ans=now/All-la,A=la,B=now/All;
	}
	printf("%lf\n",A*100);
	printf("%lf\n",B*100);
}

问题 B(3347): 染色面积

时间限制: 1 Sec  内存限制: 128 MB

题目描述

给你N个矩形,这些矩形在平面坐标系中,并且以坐标系的零点为中心,它们的边都平行于坐标轴。每个矩形由宽度和高度可以唯一确定。现在对矩形进行染色操作。下图即是样例的示意图:

 

 

现在请你计算有染色区域的面积。

输入

输入格式:

第一行包含1个整数N(1<=n<=1000000),表示矩形的个数。

接下来N行包含两个偶数XY(2<=X,Y<=10000000),分别表示宽度和高度。

输出

输出格式:

一行,表示区域面积。

样例输入

38 24 42 6

样例输出

28

单调栈维护最靠外的那一层点的坐标,然后直接计算面积就可以了。但是我犯了一个很典型的内部错误,int*int赋值给LL时是先乘,乘出一个int型,再转成LL型赋值给LL变量,也就是说,如果乘起来会炸int的话,赋值之前就已经炸了,这个值并不能完整地到LL变量里去,所以应该先乘1LL。考试的时候就差这么一点,但是也就是这一点很关键。

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<stack>
#include<algorithm>
using namespace std;
const int Max=1000000;
struct node{
	int x,y;
	bool operator<(const node &X)const{
		if(x==X.x)return y>X.y;
		return x<X.x;
	}
}A[Max+10];
int N;
long long Ans;
stack<node>Q;
void getint(int &num){
    char c;int flag=1;num=0;
    while((c=getchar())<'0'||c>'9')if(c=='-')flag=-1;
    while(c>='0'&&c<='9'){num=num*10+c-48;c=getchar();}
    num*=flag;
}
int main(){
	//freopen("area.in","r",stdin);
	//freopen("area.out","w",stdout);
	getint(N);
	for(int i=1; i<=N; ++i){
		getint(A[i].x);
		getint(A[i].y);
		A[i].x/=2,A[i].y/=2;
	}
	sort(A+1,A+1+N);
	for(int i=1; i<=N; ++i){
		while(!Q.empty()&&Q.top().y<A[i].y)	
			Q.pop();
		Q.push(A[i]);
	}
	node bef=Q.top(),tmp;Q.pop();
	Ans+=1LL*bef.x*bef.y;
	while(!Q.empty()){
		tmp=Q.top();
		Ans+=1LL*tmp.x*(tmp.y-bef.y);
		bef=tmp;
		Q.pop();
	}
	printf("%lld\n",Ans*4LL);
}

问题 C(3348): 航线变换

时间限制: 1 Sec  内存限制: 256 MB

题目描述

N个城市,它们之间都有双向的航线。一个疯狂的航空公司老板经常改变航班日程。每天他都会做以下的事情:

1.选择一个城市

2.从该城市出发没有航线到达的城市全部开通航线,同时将之前开通的从该城市出发的所有航线全部取消

举个例子,比如从城市5出发,可以达到城市1和城市2,不能到达城市3和城市4,老板选择城市5做出改变后,那么城市5就有航班可以到达城市3和城市4,同时没有航班到达城市1和城市2了。

市民们想知道有没有一天,航线形成一个完全图。即每一个城市都有到达其他所有城市的航线,或者永远不可能形成一个完全图,不管老板如何操作。写一个程序来判断

输入

第一行包含一个整数N(2<=N<=1000),表示城市的数量。城市的编号从1N

第二行包含一个整数M0<=M<=N*(N-1)/2),表示当前航班的数量。

输出

有且只有一行,如果能够形成完全图,则输出DA,如果不能形成完全图,则输出NE

样例输入

20

样例输出

DA

提示

【输入样例2

3

2

1 2

2 3

【输出样例2

NE

【输入样例3

4

2

1 3

2 4

【输出样例3

DA





问题 D(3349): 数组查询

时间限制: 5 Sec  内存限制: 512 MB

题目描述

Mirko是一个非常单纯的人,他的好朋友给他一个有N个自然数的数组,然后对他进行Q次查询.

每一次查询包含两个正整数L,R,表示一个数组中的一个区间[L,R]Mirko需要回答在这个区间中有多少个值刚好出现2次。

输入

第一行包含两个整数NQ(1<=N,Q<=500000)

第二行包含N个自然数,这些数均小于1000000000,表示数组中的元素。

接下来有Q行,每行包含两个整数LR(1<=L<=R<=N)

输出

输出包含Q行,每行包含一次查询的答案。

样例输入

5 11 2 1 1 11 3

样例输出

1

提示

【输入样例2

5 2

1 1 1 1 1

2 4

2 3

【输出样例2

0

1







  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值