2012年北京师范大学新生程序设计竞赛网络赛

好吧。。。

bnu的OJ做的相当不错。。。

然后复习unix无聊了就拿这场做了水题。。。

两题不会做悲剧。。。。。。

A. 校队的聚餐

Time Limit: 2000ms
Case Time Limit: 1000ms
Memory Limit: 65536KB
Special Judge
64-bit integer IO format:  %lld      Java class name:  Main
Submit  Status  PID: 27931
Font Size:  +   -

在辛苦了一个暑假+半个学期之后,神棍的2012赛季终于结束了。大牛决定好好地请大家吃一顿大餐!

学校周边有2n家餐馆(将它们编号为0,1,2…2n-1),校队有M名队员。现在大家在讨论去哪家餐馆吃饭,一开始大牛给出了第一种决定方案——由大牛决定去哪家餐馆。由于在大牛眼中食物只分为喜欢吃和爱吃两类,因此大牛会从2n家餐馆中等概率地随机选择一家。

但大家感觉这一方案无法体现出校队民主的优秀特点,于是提出了方案二——M名队员每人选择一家餐馆,取餐馆编号的平均数作为最后的决定。由于在大家眼中只要大牛请客去哪都行,因此所有人都会从2n家餐馆中等概率地随机选择一家。

但很快大家发现第二种方案并不能保证得出的决定是整数,于是提出了方案三——M名队员每人选择一家餐馆,将每人所选的编号取异或后作为最后的决定。由于跟方案二相同的原因,因此所有人都会从2n家餐馆中等概率地随机选择一家。

temperlsyer作为“随便”餐馆的忠实顾客,对最终结果完全不关心。他想知道的是,对于方案一、方案二、方案三,最终结果的期望分别是多少。

Input

输入只有两个整数N和M(0≤N≤30,09)。

Output

输出有三行,每行为一个小数,依次表示案一、方案二、方案三中最终结果的期望。相对或绝对误差在0.0001内均算正确。

Sample Input

1 1

Sample Output

0.50
0.50
0.50
/*
这个题前两种方案显然都是平均值
搞不明白为什么方案三不是按照m的奇偶性来判断
如果为奇数则为平均值,为偶数则为0?
不懂
 
*/
#include
#include
#include 
using namespace std;
int n,m;
double fun1(int n)
{
	double ans=pow(2.0,(double)n-1);
	return ans-0.5;
}
double fun2(int n)
{
	double ans=pow(2.0,(double)n-1);
	return ans-0.5;
}
double fun3(int n)
{
	double ans=pow(2.0,(double)n-1);
	return ans-0.5;
}
int main()
{
	while(cin>>n>>m)
	{
		printf("%.2lf\n",fun1(n));
		printf("%.2lf\n",fun2(n));
		printf("%.2lf\n",fun3(n));
	}
//	system("pause");
	return 0;
}

B. 化身

Time Limit: 1000ms
Case Time Limit: 1000ms
Memory Limit: 65536KB
64-bit integer IO format:  %lld      Java class name:  Main
Submit  Status  PID: 27934
Font Size:  +   -

三国杀最近更新的武将中有一位叫“迷之仙人”——左慈的武将,他有两个技能:(1)化身——所有人都展示武将牌后,你随机获得两张未加入游戏的武将牌,选一张置于你面前并声明该武将的一项技能,你拥有该技能且同时将性别和势力属性变成与该武将相同直到该化身被替换。在你的每个回合开始时和结束后,你可以替换化身牌,你须为新的化身重新声明一项技能。(你不可声明限定技、觉醒技或主公技)。(2)新生——你每受到1点伤害,可获得一张新化身牌。游戏过程中化身牌是不需要展示的,其他人只能通过左慈声明的技能来推断他现在化身成了哪位武将,这项艰巨的任务就交给你了~~

Input

 

第一行为整数N(2≤N≤50),代表目前摸到的武将牌的数量(假设左慈是可以摸到这么多化身牌的);一个字符串代表当前声明的技能;

接下来N行,每行一个整数,代表武将的序号;一个整数M(1≤M≤5),代表该武将的技能数量;之后M个字符串(只包括小写字母),代表武将技能(不包括限定技、觉醒技和主公技),同时用空格隔开,字符串长度<10。

Output

 

输出当前声明的技能所属的武将序号   

Sample Input

2 aaa
1 2 aaa bbb
2 1 ccc

Sample Output

1

Hint

 

每个武将的技能都是不重复的


/*
水题一枚
*/
#include
#include
#include
using namespace std;
struct hero
{
	int num;
	int m;
	char s[10][10];
}h[55];
int n;
char temp[10];
int main()
{
	while(cin>>n>>temp)
	{
		int ans;
		for(int i=0;i>num>>m;
			for(int j=0;j>str;
				strcpy(h[num].s[j],str);
				if(strcmp(str,temp)==0)
				{
					ans=num;
				}
				
			}
		}
		cout<

C. 神Lisy的智商

Time Limit: 1000ms
Case Time Limit: 1000ms
Memory Limit: 65536KB
64-bit integer IO format:  %lld      Java class name:  Main
Submit  Status  PID: 27927
Font Size:  +   -

Lisy是个很聪明的人,他有一个智力值。 

和比他聪明的人(智力值大于Lisy的,这个真心不多)辩论一次智力值会+2。
和比他笨的人(智力值小于等于Lisy)辩论一次智力会+1。
然后每个人只能辩论一次。安排一个辩论顺序。使得辩论完后Lisy的智商最高。
Orz神Lisy。

Input

第一行为一个整数K,表示数据组数。

每组数据有两行:
  第一行包含两个正整数n和p,表示要和Lisy辩论的人数,以及Lisy的初始智力值。
  第二行包含n个正整数,表示这n个人的智力值。

Output

第一行包含一个正整数,表示Lisy最终智力值的最大值。

Sample Input

2
5 91
88 98 92 94 90
1 90
90

Sample Output

99
91

Hint

输入保证:0


/*
简单贪心
将对手按智商从小到大排序
依次与智商比自己大的人辩论
最后再与智商比自己低的人辩论就好
*/
#include
#include
using namespace std;
int a[1005];
int main()
{
	int T;
	cin>>T;
	while(T--)
	{
		int n,p;
		cin>>n>>p;
		for(int i=0;i>a[i];
		}
		sort(a,a+n);
		int flag=0;
		for(int i=0;i

D. 整数边直角三角形

Time Limit: 1000ms
Case Time Limit: 1000ms
Memory Limit: 65536KB
64-bit integer IO format:  %lld      Java class name:  Main
Submit  Status  PID: 27945
Font Size:  +   -

我国是最早发现勾股定理的国家,《周髀算经》记载的古人商高关于勾股定理的应用距今已有三千多年的历史。事实上,古人对于勾股定理的研究主要是针对整数边直角三角形。整数边直角三角形是指两条直角边和斜边都为整数的直角三角形。关于整数边直角三角形有一个有趣的结论:以任何大于2的素数为直角边的整数边直角三角形唯一存在。现在就希望你帮忙找出给定素数作为一直角边的整数边直角三角形。

Input

 

第一行一个正整数T(T<=100),表示一共有多少组数据,接下来T行,每一组数据一行,含有一个大于2的素数P(27)。

Output

 

对于每组数据,输出一行为给定素数作为一直角边的整数边直角三角形三边长,按从小到大的顺序输出,以空格隔开。

Sample Input

2
3
5

Sample Output

3 4 5
5 12 13

Hint

请各位注意,此题需要使用long long,int的表示范围只有109


/*
简单数学证明题
勾股定理+平方差公式易证三边为p,(p^2-1)/2,(p^2+1)/2;
*/
#include
using namespace std;
int main()
{
	int T;
	long long p;
	cin>>T;
	while(T--)
	{
		cin>>p;
		cout<

E. 我爱背单词

Time Limit: 1000ms
Case Time Limit: 1000ms
Memory Limit: 65536KB
64-bit integer IO format:  %lld      Java class name:  Main
Submit  Status  PID: 27935
Font Size:  +   -

为了准备GRE考试,大玉儿每天都要背单词。新东方的老师说,背单词就是不断地重复,于是他制定了一项计划,第一天初次记忆之后,在以后的某些天(比如第二天,第四天,第七天,第十五天,第三十天)再把这些单词看一遍。他发现这个方法效果很好,但是每个月总有那么几天,他需要看非常非常多的单词。于是,他想写个程序来知道某一天需要看多少个单词。

大玉儿一共要背D天的新单词(即没有复习的情况下,要连续背D天),每天背的新单词个数是N1,N2,…ND。他又制定了K个复习点,R1,R2,…,RK,表示在背完某天单词的第R1天,第R2天,……,第RK天,他会把那天的单词再复习一遍(所有D天的新单词都会按照这个计划复习)。Ri=1,则说明背单词当天就复习一遍,Ri=2表示背新单词的后一天会复习一遍。

接下来,大玉儿会有M个询问,Q1,Q2,…,QM,第i个询问表示大玉儿想知道第Qi天会看多少个单词(包括当天要记的新单词)。

Input

 

测试数据有多组,第一行是一个整数T(0

对于每一组数据,第一行是一个正整数D(1<=D<=100),接下来一行有D个整数N1 N2 … ND,每个数之间用空格隔开,Ni表示大钰儿在第i天要看的新单词的数量(1<=Ni<=2000)。第三行有一个正整数K(1<=K<=100),表示有K个复习点。第四行有K个整数R1 R2 … RK,表示这K个复习点的时间(保证R1

Output

 

对于每组数据,对每个询问输出一行,第i行表示第Qi天大钰儿要看的单词数。

Sample Input

1
3
3 5 10
3
2 3 5
10
1 2 3 4 5 6 7 8 9 10

Sample Output

3
8
18
15
13
5
10
0
0
0

/*
简单hash+模拟
*/

#include
#include
#include
#include
using namespace std;
int D,K,M;
int n[105];
int r[105];
int hash[10005];
int main()
{
	int T;
	scanf("%d",&T);
	while(T--)
	{
		memset(hash,0,sizeof(hash));
		memset(n,0,sizeof(n));
		memset(r,0,sizeof(r));
		scanf("%d",&D);
		for(int i=1;i<=D;i++)
		{
			scanf("%d",&n[i]);
			hash[i]=n[i];
		}
		scanf("%d",&K);
		for(int i=1;i<=K;i++)
		{
			scanf("%d",&r[i]);
		}
		for(int i=1;i<=100;i++)
		{
			for(int j=1;j<=K;j++)
			{
				hash[i+r[j]-1]+=n[i];
			}
		}
		scanf("%d",&M);
		while(M--)
		{
			int q;
			scanf("%d",&q);
			printf("%d\n",hash[q]);
		}
	}
//	system("pause");
	return 0;
}

F. Soft Kitty

Time Limit: 1000ms
Case Time Limit: 1000ms
Memory Limit: 65536KB
64-bit integer IO format:  %lld      Java class name:  Main
Submit  Status  PID: 27937
Font Size:  +   -

laimao很喜欢这首“BigBang”里的“Soft Kitty”,这首歌的歌词很简单只有6句,"soft kitty, warm kitty, little ball of fur,happy kitty, sleepy kitty, purr purr purr.",她总是唱着玩儿。现在她无聊了决定换一个玩法,你来说出一个数字n,她来唱出第n(1 ≤ n ≤ 10^9)句歌词。注意了她的唱法是,第i次唱这首歌时,每句歌词重复2^(i-1)次。就是像这样,“soft kitty, warm kitty, little ball of fur, happy kitty, sleepy kitty, purr purr purr, soft kitty, soft kitty, warm kitty, warm kitty, little ball of fur, little ball of fur,……”你能帮助她输出第n句歌词么(不包括标点)?

Input

多组数据,第一行是一个整数K(0

Output

输出对应歌词

Sample Input

8
1
2
3
4
5
6
7
8

Sample Output

soft kitty
warm kitty
little ball of fur
happy kitty
sleepy kitty
purr purr purr
soft kitty
soft kitty

/*
模的简单应用
细心模拟就好
*/
#include
#include
using namespace std;
int n;
char s[6][30]={{"soft kitty"},{"warm kitty"},{"little ball of fur"},{"happy kitty"},{"sleepy kitty"},{"purr purr purr"}}; 
int cal(int n)
{
	int flag=1;
	int res=n;
	int temp=6;
	while(res>0)
	{

		res=res-flag*6;
		flag=flag*2;
	}
	flag/=2;
	res=res+flag*6;
	return (res-1)/flag;
}
int main()
{
	int T;
	cin>>T;
//	cout<>n;
		if(n<=6)
		{
			cout<

G. 找规律问题

Time Limit: 1000ms
Case Time Limit: 1000ms
Memory Limit: 65536KB
64-bit integer IO format:  %lld      Java class name:  Main
Submit  Status  PID: 27940
Font Size:  +   -

观察如下的序列

1)1

2)11

3)21

4)1211

5)111221

6)312211

如果您一眼看出规律了,Orz高智商 

没看出来也没关系,规律是酱紫的:

比如第3行 21  1个2和1个1  把数字抽出来 1211 得到第4行

现在对于给定任意一个N  输出第N行序列

Input

 

第一行为T 表示数据组数 (T<=100)

接下来T行每行有一个整数N (0

Output

对于每组数据,输出那一行序列

Sample Input

2
3 
4

Sample Output

21
1211

Hint

 

保证给定的N满足序列不会有连续十个数字是相同的,保证串长不超过1000


/*
简单模拟一下就好
打表就不要妄想了。。(眼睛花掉了。。)
*/
#include
using namespace std;
char dp[25][1005];
int len[25];
void init()
{
	dp[1][1]='1';
	dp[2][1]='1';
	dp[2][2]='1';
	len[1]=1;
	len[2]=2;
	for(int i=2;i<20;i++)
	{
		int k=0;
		for(int j=1;j<=len[i];j++)
		{
			int cnt=1;
			while(dp[i][j]==dp[i][j+1])
			{
				cnt++;
				j++;
			}
			dp[i+1][++k]=cnt+'0';
			dp[i+1][++k]=dp[i][j];
		}
		len[i+1]=k;
	}
}
int main()
{
	init();
	int T;
	cin>>T;
	while(T--)
	{
		int n;
		cin>>n;
		for(int i=1;i<=len[n];i++)
		{
			cout<

 


H. Triangle

Time Limit: 1000ms
Case Time Limit: 1000ms
Memory Limit: 65536KB
Special Judge
64-bit integer IO format:  %lld      Java class name:  Main
Submit  Status  PID: 27932
Font Size:  +   -


 

如图的三角形,三边边长分别为AB=a,BC=b,CA=c,并且AA’/AB=p1,BB’/BC=p2,CC’/CA=p3;

现在对于给定的a,b,c和p1,p2,p3,请你计算图中红黄绿三部分的面积。

Input

 

第一行为一个T 表示测试数据组数 (T<=1000)

接下来的T行

每行先是3个整数 依次为 a b c  0

然后是3个两位小数 依次为p1 p2 p3  0.00

Output

 

对于每组数据 输出一行 分别为红色 黄色 绿色部分的面积

中间用空格隔开 行末没有空格

答案误差在0.0001内即可

Sample Input

2
4 4 4 0.25 0.25 0.25
10 15 20 0.2 0.3 0.4

Sample Output

2.13175484 0.39970403 4.39674436
14.68004304 7.41819926 50.52019544


自己木有做出来。。。

看题解的说。。



 

I. 乘车问题

Time Limit: 1000ms
Case Time Limit: 1000ms
Memory Limit: 65536KB
64-bit integer IO format:  %lld      Java class name:  Main
Submit  Status  PID: 27930
Font Size:  +   -

大玉儿最近在备战GRE考试。听说GRE数学非常简单,大玉儿想直接挑战难题。

新东方的老师给他推荐了《猴哥112数学难题》。

112难题的第一题描述如下:

Sixty-eight people are sitting in 20 cars and each car contains at most 4 people. What is the maximum possible number of cars that could contain exactly 1 of the 68 people?

题目的意思是说,68个人坐20辆车,每辆车最多坐4个人,问最多可能有多少辆车里面只坐着一个人?如果你在45秒钟之内算出了答案4,那么恭喜你,你的GRE数学一定能拿满分。

大玉儿并不想沉浸在这么简单的题目里面,于是他把这道题改进了一下:

P个人乘坐N辆车,每辆车最多坐E个人,如果要求每辆车至少坐一个人,那么可能会有多少辆车里面恰好坐着K个人?给出其上下界。

比如,10个人乘坐7辆车,每辆车最多可坐4个人,那么有多少辆车可能只坐了1个人呢?

1.选3辆车每辆坐2个人,剩下4辆车每辆坐1个人,于是至少有4辆车只坐一个人。

2.选6辆车每辆坐1个人,剩下的一辆车坐4个人。于是最多可以有6辆车只坐一个人。

所以,你需要给出这样的答案:至少有4辆,最多有6辆车里面恰好只坐了1个人。

大玉儿想了想,这个题目似乎没那么简单,作为程序猿,他想写一个程序来解决这个问题。

Input

输入数据有多组,第一行为一个整数T(0

每一行包括4个整数,P N E K,中间用空格隔开。其中1<=P<=10000, 1<=N<=100, 1<=E<=100, 0<=K<=10000。输入数据保证P<=N*E并且N<=P。

Output

对于每一组数据,输出一行,包括2个整数a b,用空格隔开,表示至少有a辆车、最多有b辆车里面恰好坐着K个人。

注意,每辆车至少得坐一个人。

Sample Input

3
68 20 4 1
10 7 4 1
6 3 3 2

Sample Output

0 4
4 6
1 3

晕。。刚刚发现原来有官方解题报告。。



 

A. 校队的聚餐

本题在校队内部讨论过程中就被定义为游离在五个难度等级(简单,中下,中,中上,难)之外“坑题”。

   本题考察一些简单的数学功底

 方案一的结果只要按期望的定义去算就可以了,因为是每个数被取到的概率相等,所以直接(0+1+...+2^n-1)/2^n = (2^n-1)/2。

   方案二也是只需要比较基础的概率知识:相互独立事件中,和的期望等于期望的和。平均值 = 所有人和的期望/人数 =  每人期望的和/人数。又因为每个人的期望相同,所以直接等于一个人的期望*人数/人数 =一个人的期望 也就是方案一的结果。

    方案三稍微复杂一点(只是稍微)。很容易想到在问题中二进制中的每一位实际上都是相互独立的,故每一位可以单独考虑。可以简单的考虑位数为1的情况(也就是只有0和1)。一个人取异或后的结果为50%为0、50%为1。前两个人取异或后的结果为50%*50%+50%*50%=50%为0、50%*50%+50%*50%=50%为1,前三个人取异或后的结果为50%*50%+50%*50%=50%为0、50%*50%+50%*50%=50%为1……不管多少人取异或后每一位都是50%为0、50%为1,相当于方案一的取法,或者也推式子算(1+2+4+8+...+2^(n-1))/2 = (2^n-1)/2。

     综上,三种方案的结果的期望都是(2^n-1)/2。

B. 化身

本题是一道字符串处理的简单题,可利用结构体去存每个技能所对应的武将标号,最后扫一遍所有的技能找出给定的技能所对应的武将编号即可。

C.神Lisy的智商

本题的基本出发点是要对智商进行排序,同时从贪心的思想去思考:要想取得最大的智商值,肯定要先和神Lisy的当前智商值最接近的且比他大的人辩论。这样排序过后依次操作即可~~~同时在校队讨论题目过程中将此题的数据缩小,所以每次找到比当前值大的最小的智商值进行操作+2,直到没有比当前值大的为止,对剩下的进行+1操作。


D. 整数边直角三角形

由于题目中已经给出结论:以任何大于2的素数为直角边的整数边直角三角形唯一存在,同时在初中时大家一定见过这样的整数边直角三角形:7,24,25  11,60,61…..根据题目给出的结论,我们可以推出p^2=(a-b)(a+b),其中p是素数,所以a-b必定为1。所以剩下的a+b就是p^2了,然后就可以解方程了,需要注意(10^7)^2超过了int的表示范围,所以需要使用long long。

E. 我爱背单词

由于题目数据量不算太大,因此直接模拟for一遍就可以了

for(int i=1;i<=d;i++)

   for(int j=0;j

           word[i+r[j]-1]+=n[i];

}

和G题差不多,在M个询问前就把1到D+Rk-1天的单词数算出来,询问过程中如果Qi>D+Rk-1直接输出0,else输出word[Qi]。需要注意的是有多组数据,因此在输入每一组之前都要把word数组清零!


F. Soft Kitty

据出题者说本题的解题方法主要是2进制问题,这里说一个用数学方法推出的过程:

唱第m次这首歌时,该次需要唱6*2^m-1句;唱了m次之后总共唱了

句歌词;而对于给定的n,我们可以利用上式大致推算出m的值,m=log2(n/6+1)这就不难搞出第n句所要输出的歌词了吧,同时这个式子也在暗示我们本题确实与2进制有关~~~


G. 找规律问题

本题也是一道字符串处理题,属于中等难度。规律题目中已经给了,第i行的字符串是根据第i-1行的字符串得来的,看到n<=20可能会想到手动打表直接交上去,但是在比赛过程中能一次搞定还是很有难度的,况且n=20时输出的字符串长度会达到200+!!!这在编译器中一行是无法看全的,很容易CE!!

因此模拟一下就行了,在模拟过程中要注意:应比较当前字符与上一个字符 是否相同,不同的话就生成字符串,否则频数+1。这个模拟的过程应在输入n前完成,以便节约时间,也就是“离线打表”~~当然如果n>50的话可能会RE!


H. Triangle

这是一道不太常见的几何题,因为需要添加辅助线才能简化推导过程,当然用正弦定理和余弦定理来回倒角和边也是可以的(此题对精度的要求不高,而且是Special Judge),不过会很麻烦的 = =||

辅助线的构造方法:作B’D∥A’C并设BD=x,x可由△AA’O∽△ADB’以及△BB’D∽△BCA’推出,这样AD的长度也是可求的!下面第一个图中的黄色部分的面积就可利用相似比的平方求出,i.e. 对于△ADB’的面积,它的高与△ABC的高也存在相似比关系,这样就可以推导出△AA’O的面积,原图中其他两块黄色部分的面积可利用类似的方法求出,黄色面积的和即为S(黄)

对于绿色部分的面积,S’(绿)=△ABB’—(两块黄色的面积),这里△ABB’与,△ADB’等高的,只是底不同而已~~~。类似地可以求得三块绿色面积的总和

最后红色部分的面积S(红)=S(总)—S(绿)—S(黄)

总的面积可以用海伦公式求解 。

I. 乘车问题


 

这道题要求输出a 和b,我们把a称作下界,b称作为上界。

 

首先需要特殊判断的是只有一辆车(N==1)的情况。这个时候,所有人都只坐在这一辆车里面。所以看是否总人数为K,如果为K,则上下界均为1,如果不为K则上下界为0。再特判的就是K>E的情况,这个情况下界上界都是输出0。

 

下面讨论的是N不为1且K<=E的情况。

 

求上界比较简单。

假设最多有C辆车恰好坐K个人,那么K*C就是已经安排好了的人数。

P-K*C则是未安排的人数,N-C表示未安排的车辆。

它们必须满足下面的条件:

P-K*C >= N-C

P-K*C <= (N-C)*E

解上面两个方程,得   C<=(P-N)/(K-1) 并且 C<=(N*E-P)/(E-K),取其中较小的值就是上界。

K==1或者E==K的时候只需要计算上述有意义的一个值。

 

下面说说下界的计算。

首先,如果E==1,那么所有的车都是有且仅有一个人,此时下界就是N(也是P,因为这时P=N)。

接下来就是E不等于1的情况:

1.    K==E,那么我们先把每辆车都安排E-1个人,如果人已经安排完了,即(E-1)*N - P >= 0,我们就说,至少存在一种安排情况,使得没有一辆车坐E个人(即这时下界为0)。如果(E-1)*N < P,那么还剩下P-(E-1)*N个人,这几个人必须都坐在满的车里面了,即至少有P-(E-1)*N辆车里面有E个人。

 

2.    K==1, 我们则把每辆车安排至少2个人,如果此时人还没安排完或者恰好安排完,即2*N - P <= 0,我们就说,存在一种安排情况,使得没有一辆车里面只有1个人(即这时下界为0)。否则,至少会有2*N-P辆车里面只有一个人。(这里就是解方程,x+y=N, x+2y=P,x表示只一个人的车数,y表示只坐2个人的,得x=2N-P)。

 

3.    K!=1 && K!=E时,我们来考虑什么样的情况才有可能下界不为0。

如果 N*(K-1)>=P,我们可以找到一种方法,使得每一辆车都少于K个人,

如果 N*(K+1)<=P,那么显然我们可以找到一种方法,使得每一辆车都多于K个人。

也就是说,只有当 N*(K-1)

对于这样的情况,我们可以有一种安排方法,使得每辆车都是K-1或者K个人(如果N*K<=P),或者K个人和K+1个人(如果P>N*K)。

假设现在有若干个K-1和若干个K(对于K和K+1的情况是一样的)。我们可以将每两个K分解成K-1和K+1,最后最多只会剩下一个K。所以,一定存在一种分配方法,使得所有的车只可能会有K+1,K,K-1个人,而且最多只有一个K

 

这时候,我们把情况再细分一下。

 

先考虑K!=2并且K!=E-1的情况:因为N不等于1(最开始就讨论了),而这时候最多只有一个车里面有K,另外的车里面是K-1或者K+1,我们显然可以把这个K和一辆K-1变成K+1,K-2,或者把这辆K和一辆K+1变成K-1和K+2。所以,对于K!=2并且K!=E-1的情况,可以找到一种安排,使得所有的车都不含K。这种情况,下界就是0。

 

最后就是讨论K==2或者K==E-1的情况了:我们之前证明过,这种情况含K的车最多只有一辆,所以我们只要看有没有这一辆车就行了。

 

这里会有一个特例,即当K既等于E-1,又等于2。即K=2,E=3的情况。

对于这种特殊的情况,我们来看看什么情况下有这个2。

对于一辆车只有3种载人情况。

如果没有载2个人的车,那只有载着1个人和3个人的车。

可得下面的方程:

x+y = N

x+3y = P

这时候x,y要有整数解,必须满足P-N能被2整除。所以,这种情况下,如果P-N是偶数,那么就可以不含有K=2的车,下界为0,否则一定会有一辆K=2的车。

 

除了这种情况,那么K要么只等于E-1,要么只等于2。

什么时候必须有一个K==E-1呢?当且仅当N-1辆车已经装满了E个人,还剩下恰好一辆车和E-1个人。所以当 P=N*E-1时,肯定会有一辆坐着E-1个人的车。

什么时候必须有一个K==2呢?那当且仅当N-1辆车已经装了1个人,还剩下恰好一辆车和2个人。所以当P=N+1的时候,肯定会有一辆坐着2个人的车。

 

综上所述,这道题的解题按如下步骤讨论:(如果想自己先写,就不要看这部分了)

1.    如果K>E或者K<=0,则a=b=?; 结束

2.    如果N==1,则a=b=?; 结束

3.    如果E==1,则a=b=?; 结束

4.    先计算b:

a)     如果K==1,b=?;

b)     否则如果K==E,b=?;

c)     否则b=?。

5.    再计算a:

a)     如果 P<=(K-1)*N || P>=(K+1)*N ,a=?;结束;

b)     否则如果E==3 && K==2, a=?;结束;

c)     否则如果K==1, a=?;结束;

d)     否则如果K==E, a=?;结束;

e)     否则如果K==2, a=?;结束;

f)      否则如果K==E-1,a=?;结束;

g)     否则 a = 0,结束。


 

A. 校队的聚餐

本题在校队内部讨论过程中就被定义为游离在五个难度等级(简单,中下,中,中上,难)之外“坑题”。

   本题考察一些简单的数学功底

 方案一的结果只要按期望的定义去算就可以了,因为是每个数被取到的概率相等,所以直接(0+1+...+2^n-1)/2^n = (2^n-1)/2。

   方案二也是只需要比较基础的概率知识:相互独立事件中,和的期望等于期望的和。平均值 = 所有人和的期望/人数 =  每人期望的和/人数。又因为每个人的期望相同,所以直接等于一个人的期望*人数/人数 =一个人的期望 也就是方案一的结果。

    方案三稍微复杂一点(只是稍微)。很容易想到在问题中二进制中的每一位实际上都是相互独立的,故每一位可以单独考虑。可以简单的考虑位数为1的情况(也就是只有0和1)。一个人取异或后的结果为50%为0、50%为1。前两个人取异或后的结果为50%*50%+50%*50%=50%为0、50%*50%+50%*50%=50%为1,前三个人取异或后的结果为50%*50%+50%*50%=50%为0、50%*50%+50%*50%=50%为1……不管多少人取异或后每一位都是50%为0、50%为1,相当于方案一的取法,或者也推式子算(1+2+4+8+...+2^(n-1))/2 = (2^n-1)/2。

     综上,三种方案的结果的期望都是(2^n-1)/2。

B. 化身

本题是一道字符串处理的简单题,可利用结构体去存每个技能所对应的武将标号,最后扫一遍所有的技能找出给定的技能所对应的武将编号即可。

C.神Lisy的智商

本题的基本出发点是要对智商进行排序,同时从贪心的思想去思考:要想取得最大的智商值,肯定要先和神Lisy的当前智商值最接近的且比他大的人辩论。这样排序过后依次操作即可~~~同时在校队讨论题目过程中将此题的数据缩小,所以每次找到比当前值大的最小的智商值进行操作+2,直到没有比当前值大的为止,对剩下的进行+1操作。


D. 整数边直角三角形

由于题目中已经给出结论:以任何大于2的素数为直角边的整数边直角三角形唯一存在,同时在初中时大家一定见过这样的整数边直角三角形:7,24,25  11,60,61…..根据题目给出的结论,我们可以推出p^2=(a-b)(a+b),其中p是素数,所以a-b必定为1。所以剩下的a+b就是p^2了,然后就可以解方程了,需要注意(10^7)^2超过了int的表示范围,所以需要使用long long。

E. 我爱背单词

由于题目数据量不算太大,因此直接模拟for一遍就可以了

for(int i=1;i<=d;i++)

   for(int j=0;j

           word[i+r[j]-1]+=n[i];

}

和G题差不多,在M个询问前就把1到D+Rk-1天的单词数算出来,询问过程中如果Qi>D+Rk-1直接输出0,else输出word[Qi]。需要注意的是有多组数据,因此在输入每一组之前都要把word数组清零!


F. Soft Kitty

据出题者说本题的解题方法主要是2进制问题,这里说一个用数学方法推出的过程:

唱第m次这首歌时,该次需要唱6*2^m-1句;唱了m次之后总共唱了

句歌词;而对于给定的n,我们可以利用上式大致推算出m的值,m=log2(n/6+1)这就不难搞出第n句所要输出的歌词了吧,同时这个式子也在暗示我们本题确实与2进制有关~~~


G. 找规律问题

本题也是一道字符串处理题,属于中等难度。规律题目中已经给了,第i行的字符串是根据第i-1行的字符串得来的,看到n<=20可能会想到手动打表直接交上去,但是在比赛过程中能一次搞定还是很有难度的,况且n=20时输出的字符串长度会达到200+!!!这在编译器中一行是无法看全的,很容易CE!!

因此模拟一下就行了,在模拟过程中要注意:应比较当前字符与上一个字符 是否相同,不同的话就生成字符串,否则频数+1。这个模拟的过程应在输入n前完成,以便节约时间,也就是“离线打表”~~当然如果n>50的话可能会RE!


H. Triangle

这是一道不太常见的几何题,因为需要添加辅助线才能简化推导过程,当然用正弦定理和余弦定理来回倒角和边也是可以的(此题对精度的要求不高,而且是Special Judge),不过会很麻烦的 = =||

辅助线的构造方法:作B’D∥A’C并设BD=x,x可由△AA’O∽△ADB’以及△BB’D∽△BCA’推出,这样AD的长度也是可求的!下面第一个图中的黄色部分的面积就可利用相似比的平方求出,i.e. 对于△ADB’的面积,它的高与△ABC的高也存在相似比关系,这样就可以推导出△AA’O的面积,原图中其他两块黄色部分的面积可利用类似的方法求出,黄色面积的和即为S(黄)

对于绿色部分的面积,S’(绿)=△ABB’—(两块黄色的面积),这里△ABB’与,△ADB’等高的,只是底不同而已~~~。类似地可以求得三块绿色面积的总和

最后红色部分的面积S(红)=S(总)—S(绿)—S(黄)

总的面积可以用海伦公式求解 。

I. 乘车问题


 

这道题要求输出a 和b,我们把a称作下界,b称作为上界。

 

首先需要特殊判断的是只有一辆车(N==1)的情况。这个时候,所有人都只坐在这一辆车里面。所以看是否总人数为K,如果为K,则上下界均为1,如果不为K则上下界为0。再特判的就是K>E的情况,这个情况下界上界都是输出0。

 

下面讨论的是N不为1且K<=E的情况。

 

求上界比较简单。

假设最多有C辆车恰好坐K个人,那么K*C就是已经安排好了的人数。

P-K*C则是未安排的人数,N-C表示未安排的车辆。

它们必须满足下面的条件:

P-K*C >= N-C

P-K*C <= (N-C)*E

解上面两个方程,得   C<=(P-N)/(K-1) 并且 C<=(N*E-P)/(E-K),取其中较小的值就是上界。

K==1或者E==K的时候只需要计算上述有意义的一个值。

 

下面说说下界的计算。

首先,如果E==1,那么所有的车都是有且仅有一个人,此时下界就是N(也是P,因为这时P=N)。

接下来就是E不等于1的情况:

1.    K==E,那么我们先把每辆车都安排E-1个人,如果人已经安排完了,即(E-1)*N - P >= 0,我们就说,至少存在一种安排情况,使得没有一辆车坐E个人(即这时下界为0)。如果(E-1)*N < P,那么还剩下P-(E-1)*N个人,这几个人必须都坐在满的车里面了,即至少有P-(E-1)*N辆车里面有E个人。

 

2.    K==1, 我们则把每辆车安排至少2个人,如果此时人还没安排完或者恰好安排完,即2*N - P <= 0,我们就说,存在一种安排情况,使得没有一辆车里面只有1个人(即这时下界为0)。否则,至少会有2*N-P辆车里面只有一个人。(这里就是解方程,x+y=N, x+2y=P,x表示只一个人的车数,y表示只坐2个人的,得x=2N-P)。

 

3.    K!=1 && K!=E时,我们来考虑什么样的情况才有可能下界不为0。

如果 N*(K-1)>=P,我们可以找到一种方法,使得每一辆车都少于K个人,

如果 N*(K+1)<=P,那么显然我们可以找到一种方法,使得每一辆车都多于K个人。

也就是说,只有当 N*(K-1)

对于这样的情况,我们可以有一种安排方法,使得每辆车都是K-1或者K个人(如果N*K<=P),或者K个人和K+1个人(如果P>N*K)。

假设现在有若干个K-1和若干个K(对于K和K+1的情况是一样的)。我们可以将每两个K分解成K-1和K+1,最后最多只会剩下一个K。所以,一定存在一种分配方法,使得所有的车只可能会有K+1,K,K-1个人,而且最多只有一个K

 

这时候,我们把情况再细分一下。

 

先考虑K!=2并且K!=E-1的情况:因为N不等于1(最开始就讨论了),而这时候最多只有一个车里面有K,另外的车里面是K-1或者K+1,我们显然可以把这个K和一辆K-1变成K+1,K-2,或者把这辆K和一辆K+1变成K-1和K+2。所以,对于K!=2并且K!=E-1的情况,可以找到一种安排,使得所有的车都不含K。这种情况,下界就是0。

 

最后就是讨论K==2或者K==E-1的情况了:我们之前证明过,这种情况含K的车最多只有一辆,所以我们只要看有没有这一辆车就行了。

 

这里会有一个特例,即当K既等于E-1,又等于2。即K=2,E=3的情况。

对于这种特殊的情况,我们来看看什么情况下有这个2。

对于一辆车只有3种载人情况。

如果没有载2个人的车,那只有载着1个人和3个人的车。

可得下面的方程:

x+y = N

x+3y = P

这时候x,y要有整数解,必须满足P-N能被2整除。所以,这种情况下,如果P-N是偶数,那么就可以不含有K=2的车,下界为0,否则一定会有一辆K=2的车。

 

除了这种情况,那么K要么只等于E-1,要么只等于2。

什么时候必须有一个K==E-1呢?当且仅当N-1辆车已经装满了E个人,还剩下恰好一辆车和E-1个人。所以当 P=N*E-1时,肯定会有一辆坐着E-1个人的车。

什么时候必须有一个K==2呢?那当且仅当N-1辆车已经装了1个人,还剩下恰好一辆车和2个人。所以当P=N+1的时候,肯定会有一辆坐着2个人的车。

 

综上所述,这道题的解题按如下步骤讨论:(如果想自己先写,就不要看这部分了)

1.    如果K>E或者K<=0,则a=b=?; 结束

2.    如果N==1,则a=b=?; 结束

3.    如果E==1,则a=b=?; 结束

4.    先计算b:

a)     如果K==1,b=?;

b)     否则如果K==E,b=?;

c)     否则b=?。

5.    再计算a:

a)     如果 P<=(K-1)*N || P>=(K+1)*N ,a=?;结束;

b)     否则如果E==3 && K==2, a=?;结束;

c)     否则如果K==1, a=?;结束;

d)     否则如果K==E, a=?;结束;

e)     否则如果K==2, a=?;结束;

f)      否则如果K==E-1,a=?;结束;

g)     否则 a = 0,结束。

你可能感兴趣的:(BUAA,Training,2013)