2015级C++第三次练习赛

自学了一点C++的皮毛,带着C的基础做完了这次。因为出练习赛的时候他们没有学数组和字符串什么的,所以最好也不让用。就是这些基础的内容,然而难度却让我卡了很久。对我这种菜鸡来说还是很棘手的,可能是因为涉及简单的算法吧。
另外自学的C++写出来的代码如果很丑也请海涵。

045-A 大神杀

题目描述

我相信大家知道什么叫回文数。
现在给你一个浮点数,请你判断其整数部分和小数部分是否回文。
例如32.23就是一个浮点回文数。3.223就不是。

输入

输入多组数据。
每组数据只有一行,为一个浮点n(n>0且n<100000)。

输出

每组数据输出一行为"Yes"或"No"。(没引号)

输入样例

32.23
3.223

输出样例

Yes
No

Hint

保证用double可以做
输入最多到小数点后五位,且末尾不为0.

精度设置:double eps=1e-6;

既然保证用double就可以做了,那就懒得用字符串判断了,虽然可能字符串更简单点。
#include<cstdio>
#include<iostream>
using namespace std; /*标准开头*/ 

#define eps 1e-6

bool judge(double x)
{
	x += eps;
	
	long long t;
	t = 100000 * x;
	
	if((int(x)) % 10 != (int(10 * x)) % 10)	return false;
	if((int(x / 10)) % 10 != (int(100 * x)) % 10)	return false;
	if((int(x / 100)) % 10 != (int(1000 * x)) % 10)	return false;
	if((int(x / 1000)) % 10 != (int(10000 * x)) % 10)	return false;
	if((int(x / 10000)) % 10 != t % 10)	return false;    /*10位整数超过int范围*/
	return true;
}


int main(){
	
	double x;
	
	while((scanf("%lf",&x)) != EOF)
	{
		if(judge(x))	cout << "Yes" << endl;
		else			cout << "No" << endl;
	}
} 

049-B 盗墓笔记之怒海潜沙
最小公倍数,懒得再贴一次了. edge nmsl!!!!!

043-C 且听风吟之呆逼二三事

题目描述

wzc是Tera里且听风吟公会的会长,本着为会员着想的心理,努力发展公会,公会人数也是日益壮大,慢慢的就加入了各大公会战,野外打狗的行列。
但是公会的某个妹子突然被呆比抢走并且已经发展到线下了(hhhh
广大会员和会长怎么能忍,随着呆比的发展,渐渐不见他上线,所以大家偷偷决定将他驱逐公会,但是会长wzc是个民主的会长(权限狗),他决定打开公会仓库,让呆比拿走一些金子作为他两个月来的贡献,但是wzc比较大方(抠门),定了下面的规矩:
wzc和呆比轮流取金子,wzc先取,第1次可以取任意多的金币,但不能全部取完.以后每次取的金子不能超过上次取的2倍,如果最后是wzc取完那么呆比取到的金子就要还回来,反之呆比可以拿走取到的金子。假设呆比和wzc都竭尽全力想要赢。
wzc沉迷于公会战和各种事物不能自拔所以需要你来判断呆比能不能全身而退。

输入

输入有多组
.每组1行只有一个数n,代表仓库里的金子数,wzc很穷(有钱)所以2<=n<2^31。

输出

如果wzc取完 则输出"Oh,yes!" 如果呆比取完 则输出"Oh,holly shit!"(我英语学的不好请原谅)

输入样例

2
10000

输出样例

Oh,holly shit!
Oh,yes!

看上去就是一个博弈游戏,虽然我也不知道是什么,先推导几个找规律吧。2,3,5,8都是先手lose的状态,很容易联想到斐波那契数,所以这道题其实是个斐波那契博弈。但是我比较菜没办法证明,只能百度斐波那契博弈了。
开始推导的时候12还推错了,其实先手可以只取1个,无论后手是1还是2,先手都可以让后手陷入8的先手lose状态。所以12其实是先手win的。
#include<cstdio>
#include<iostream>
using namespace std; /*标准开头*/ 

int main(){
	
	int a1,a2,b,n;
	
	while((scanf("%d",&n)) != EOF){
		
		a1 = 2;a2 = 3;
		
		for(b = a1;;)
		{
			if(b == n)
			{
				cout << "Oh,holly shit!" << endl;
				break;
			}
			else if(b > n)
			{
				cout << "Oh,yes!" << endl;
				break;
			}
			else
			{
				a1 = a2;
				a2 = a1 + b;
				b = a1;
			}
		}
		
	}
	
} 
047-D 不要不要数列求和

题目描述

给你一个公式f(n,m)=(3!!+5!!+……+(2n+1)!!)-(2!!+4!!+……+(2m)!!),求公式的值。结果对10007取模。

输入

输入多组数据。
每组数据只有一行,为两个正整数n和m(1<=n,m<=100)。

输出

输出公式的结果。

输入样例

1 1

输出样例

1

Hint

!!表示双阶乘。(2n)!!=246……(2n)。(2n+1)!!=135……(2*n+1)。 取模运算时尽可能边加边取模,边乘边取模。

注意当一个数为负数时,应该使用ans=((ans-sum)%mod+mod)%mod;的形式来将取模的值变为正数
貌似

看上去。。。挺水的

#include<cstdio>
#include<iostream>
using namespace std; /*标准开头*/ 

int main(){
	
	int a,b;
	long long f1,f2,l1,l2,i,ans; 
	
	while((scanf("%d%d",&a,&b)) != EOF){
		
		f1 = 0;
		f2 = 0;
		l1 = 1;
		l2 = 1;
		
		for(i = 1;i <= a;i++){
			l1 *= (2 * i + 1);
			l1 %= 10007;
			f1 += l1;
			f1 %= 10007;
		}
		
		for(i = 1;i <= b;i++){
			l2 *= 2 * i;
			l2 %= 10007;
			f2 += l2;
			f2 %= 10007;
		}
		
		ans = f1 - f2;
		
		if(f1 < f2)
			cout << ((ans % 10007) + 10007) % 10007 << endl;
		else
			cout << ans % 10007 << endl;
	}
	
}
042-E 不要不要丧心病狂

题目描述

jhljx又决定来出题了,上次上机以后有人说他是黑心学长,,噗。。。
肿么可以这样。。
松辰学妹对jhljx说不要不要丧心病狂。。jhljx说我给你出一道题,你要是答对了,你就赢了。。
松辰学妹说这还不简单啊。。
于是jhljx给了松辰学妹一个长度为n的数列A1,A2,A3……An。他说你能找出这个序列中a[i]-a[j]的最大值吗(保证i<j)?
松辰学妹说用数组啊。。jhljx说,没学数组,不准用。。用了你就跪了。。 松辰学妹说好吧。。这可怎么办呢?

输入

输入多组数据。
每组数据两行,第一行是一个正整数n(2<=n<=1000000)。第二行是n个数,每个数之间用空格隔开。保证这些数在int范围内。

输出

输出满足条件的最大值。

输入样例

2
100 20

输出样例

80

Hint

这道题尽量不要用数组,因为没有学。不用数组完全可以做。
PS:这道题没有去刻意卡内存。。

丧心病狂

还不让用数组,那么就很棘手了。这题其实可以用这样的算法:读到一个数时,先动态寻找之前的最大数,然后减去当前数。如果大于最大差值则更新最大差值。
如果是 i > j 的情况也可以用这样的算法来求。时间复杂度是O(n)。

#include<cstdio>
#include<iostream>
using namespace std; /*标准开头*/ 

int main(){
	
	int n,i;
	long long a0,a1,maxV,maxGap,last,ai;
	
	while((scanf("%d",&n)) != EOF){
		
		cin >> a0 >> a1;
		
		maxGap = a0 - a1;
		maxV = a0;
		last = a1;
		
		for(i = 2;i < n;i++){
			
			cin >> ai;
			
			if(last > maxV)
				maxV = last;
				
			if(maxV - ai > maxGap)
				maxGap = maxV - ai;
			
			last = ai;
		}
		
		cout << maxGap << endl;
	}
}
044-F jhljx学函数


swap函数,应该都会吧。

046-G 李逍遥的仙剑客栈

题目描述

有一天天臧散人Arthur到了渝州东南的仙剑客栈,发现李逍遥这小子粗心大意在上酒的时候,有的桌上多上了酒,有的桌上没上酒。唉,谁让Arthur心软呢,不忍心看李逍遥被他婶婶骂,决定帮他——收拾一排桌子。
给 你一个数n表示有多少个桌子,接下来给你一段整数序列表示每个桌上需要的酒量(假设这些桌子在一条直线上,且每个桌子之间的距离都是1),正数表示多放了 几瓶酒,负数表示应该放多少瓶酒。请你帮Arthur算一下他提着酒走的最短路程是多少。对了,Arthur体力太渣,一次只能拿一瓶酒。

输入

第一行一个数T表示有T组数据。
接下来T组数据,每组数据有2行。
第一行一个数n(1<=n<=1000),表示桌子数量,
接下来第二行有一段数列Ai(|Ai|<=1000),表示每个桌子上应该放的酒。保证数列总和为0

输出

对于每组测试数据,输出一个数,表示Arthur拿着酒走的最少总路程。

输入样例

2
3
-1 2 -1
6
-1 -1 -1 3 -1 1

输出样例

2
7

Hint

其实就是每瓶酒走的路程之和。

这题好难啊。。。而且还不让用数组。方法是每一步统计酒瓶个数(负数为需要多少个,正数为携带多少个),然后累积这些个数啤酒瓶的路程。

我估计是道经典题,不过懒得去找原题了。


#include<cmath>
#include<iostream>
using namespace std; 

int main(){
	
	int T,n,a;
	cin >> T;
	
	while(T--){
		
		cin >> n;
		int dis = 0,count = 0;
		
		while(n--){
			cin >> a;	
			dis += abs(count);
			count += a;
		}	
		
		cout << dis << endl;
		
	}	
}
初见杀之前发过了,懒得再发了。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值