个人记录——洛谷试炼场,BOSS战!【新手村】

洛谷链接
感谢萌萌,推荐给我一个消磨时光的 good place ~~

新手村主要做了BOSS战——入门综合练习1和2,感觉有点小学奥数的意思,难度不高,主要考验基础的编写代码能力、理解题意能力以及分析解决方案的能力。

  • P1478 陶陶摘苹果(升级版)

  • 题目描述
    又是一年秋季时,陶陶家的苹果树结了n个果子。陶陶又跑去摘苹果,这次她有一个a公分的椅子。当他手够不着时,他会站到椅子上再试试。

    这次与NOIp2005普及组第一题不同的是:陶陶之前搬凳子,力气只剩下s了。当然,每次摘苹果时都要用一定的力气。陶陶想知道在s<0之前最多能摘到多少个苹果。

    现在已知n个苹果到达地上的高度xi,椅子的高度a,陶陶手伸直的最大长度b,陶陶所剩的力气s,陶陶摘一个苹果需要的力气yi,求陶陶最多能摘到多少个苹果。

  • 输入格式
    第1行:两个数 苹果数n,力气s。
    第2行:两个数 椅子的高度a,陶陶手伸直的最大长度b。
    第3行~第3+n-1行:每行两个数 苹果高度xi,摘这个苹果需要的力气yi。

  • 输出格式
    只有一个整数,表示陶陶最多能摘到的苹果数。

  • 实现代码:

#include "iostream"
#include "iomanip"
#include <time.h>
using namespace std;

int main()
{
	int n,s,a,b,x[5000],y[5000],count=0;
	do
	{
	cin>>n>>s;
	cin>>a>>b;
	}
	while(n>5000 || s>1000 || a>50 || b>200);
	for(int i=0;i<n;i++)
	{
		cin>>x[i]>>y[i];
	}
	for(int i=0;i<n;i++)
		for(int j=0;j<n-i-1;j++)
		{
			if(y[j]>y[j+1])
			{
				int t=y[j];y[j]=y[j+1];y[j+1]=t;
				t = x[j];x[j]=x[j+1];x[j+1]=t;
			}
		}
	for(int i=0;i<n;i++)
	{
		if(x[i]-a-b>0)
			continue;
		else if((s = s - y[i])<0)
			break;
		else
		{
			count++;
		}
	}
	cout<<count;
	return 0;
}
  • 后记:
    这个没啥好说的。。。

- P1618 三连击(升级版)

  • 题目描述
    将1,2,…,9共9个数分成三组,分别组成三个三位数,且使这三个三位数的比例是A:B:C,试求出所有满足条件的三个三位数,若无解,输出“No!!!”。
    //感谢黄小U饮品完善题意

  • 输入格式
    三个数,A B C。

  • 输出格式
    若干行,每行3个数字。按照每行第一个数字升序排列。

  • 实现代码

#include "iostream"
#include "iomanip"
#include <time.h>
using namespace std;

int fun(int a,int b)
{
	int x1[3],x2[3];
		x1[0] = a/100;
		x1[1] = a/10%10;
		x1[2] = a%10;
	for(int i=0;i<3;i++)
	{
		if(b/100==x1[i])return 0;
		if(b/10%10==x1[i])return 0;
		if(b%10 == x1[i])return 0;
	}
	return 1;
}

int main()
{
	int a,b,c,t,count=0,x=0,num1,num2,num3,flag=0,flag2=0;
	int num[504]={0};
	do
	{
	flag2 =0;
	cin>>a>>b>>c;
	if(a>=b || a>=c || b>=c )flag2 =1;
	}
	while(flag2 == 1);

	int ori[9]={1,2,3,4,5,6,7,8,9};
	for(int i=1;i<10;i++)
	{
		for(int j=1;j<10;j++)
		{
			if(j==i)continue;
			for(int z=1;z<10;z++)
			{
				if(z==i || z==j)continue;
				t = i*100 + j*10 +z;
				num[x] = t;
				x++;
			}
		}
	}
 
	for(int i=0;i<x;i++)
	{
		int j,z;
		num1 = num[i];
		if(num1%a !=0)
			continue;
		num2 = num[i] * b / a;
		for(j=i+1;j<x;j++)
		{
			if(num2 == num[j])break;
		}

		if(j<x && fun(num1,num2))
		{
			num3 = num[i] * c/a;
			for(z=j+1;z<x;z++)
			{
				if(num3 == num[z])break;
			}

			if(z<x && fun(num2,num3) && fun(num1,num3))
			{
				flag = 1;
				cout<<num[i]<<" "<<num2<<" "<<num3<<endl;
			}
		}
	}
	if(flag==0)cout<<"No!!!"<<endl;
	return 0;
}
  • 后记:突然发现自己写代码很少敲注释啊,这样不好不好,隔段时间回来看就看不懂了。(会回来看?)这题和小红一起奋战了挺多次才100%通过测试,我的主要思路比较瓜皮,就是先把符合不重复数的三个三位数全部枚举并存起来,然后根据输入的比例挨个挨个测试是否符合条件,如果符合就输出咯。

  • P1579 哥德巴赫猜想(升级版)

  • 题目背景
    1742年6月7日哥德巴赫写信给当时的大数学家欧拉,正式提出了以下的猜想:任何一个大于9的奇数都可以表示成3个质数之和。质数是指除了1和本身之外没有其他约数的数,如2和11都是质数,而6不是质数,因为6除了约数1和6之外还有约数2和3。需要特别说明的是1不是质数。

    这就是哥德巴赫猜想。欧拉在回信中说,他相信这个猜想是正确的,但他不能证明。

    从此,这道数学难题引起了几乎所有数学家的注意。哥德巴赫猜想由此成为数学皇冠上一颗可望不可及的“明珠”。

  • 题目描述
    现在请你编一个程序验证哥德巴赫猜想。

    先给出一个奇数n,要求输出3个质数,这3个质数之和等于输入的奇数。

  • 输入格式
    仅有一行,包含一个正奇数n,其中9<n<20000

  • 输出格式
    仅有一行,输出3个质数,这3个质数之和等于输入的奇数。相邻两个质数之间用一个空格隔开,最后一个质数后面没有空格。如果表示方法不唯一,请输出第一个质数最小的方案,如果第一个质数最小的方案不唯一,请输出第一个质数最小的同时,第二个质数最小的方案。

  • 实现代码

// luogu-judger-enable-o2
#include "iostream"
#include "iomanip"
#include <time.h>
using namespace std;

int fun(int n)
{
	int i;
	for(i=2;i<n;i++)
		if(n%i == 0)break;
	if(i<n)return 0;
	return 1;
}

int main()
{
	int n,i,j,m,flag=0;
	cin>>n;
	for(i=2;i<n;i++)
	{
		if(fun(i))
		{
			for(j=i;j<n;j++)
			{
				if(fun(j))
				{
					m = n - i -j;
					if(fun(m) && m>0)
					{
						cout<<i<<" "<<j<<" "<<m;
						flag =1;
						break;
					}
				}
				if(flag ==1)break;
			}
		}
		if(flag == 1)break;
	}
}
  • 后记:这个没啥好说的。。

  • P2089 烤鸡

  • 后记:这个就不放题目和代码了,十层循环暴力枚举哦耶( ̄︶ ̄*))

  • P1426 小鱼会有危险吗

  • 题目描述
    有一次,小鱼要从A处沿直线往右边游,小鱼第一秒可以游7米,从第二秒开始每秒游的距离只有前一秒的98%。有个极其邪恶的猎人在距离A处右边s米的地方,安装了一个隐蔽的探测器,探测器左右x米之内是探测范围。一旦小鱼进入探测器的范围,探测器就会在这一秒结束时把信号传递给那个猎人,猎人在一秒后就要对探测器范围内的水域进行抓捕,这时如果小鱼还在这范围内就危险了。也就是说小鱼一旦进入探测器范围,如果能在下1秒的时间内马上游出探测器的范围,还是安全的。现在给出s和x的数据,请你判断小鱼会不会有危险?如果有危险输出’y’,没有危险输出’n’。
    //感谢黄小U饮品完善题意

  • 输入格式
    一行内输入两个实数,用空格分隔,表示s和x。均不大于100

  • 输出格式
    一行内输出’y’或者’n’表示小鱼是否会有危险。

  • 实现代码

#include <iostream>
#include <math.h>
using namespace std;
int main()
{
	double s, x;
	cin >> s >> x;
	double v = 7, len = 0;
	while (1)
	{
		if (len >= (s - x) && len <= (s + x))
		{
			len = len + v;
			if (len <= (s + x))
			{
				cout << 'y';
				return 0;
			}
			else
			{
				cout << 'n';
				return 0;
			}
		}
		else if (len > (s + x))
		{
			cout << 'n';
			return 0;
		}
		len = len + v;
		v = v * 0.98;//the next second
	}
	return 0;
}
  • 后记:这个题本来非常简单,但是无奈我理解成了小鱼也可以发现危险,在进入危险区后的一秒可以选择向左或向右游 ,弄了半天过不了测试点,再读题意才发现是只能往右游。。只能说这是个和我一样憨憨的小鱼吧。
    所以一定要理解清楚题目的意思…略坑。
  • P1464 Function (੭ˊᵕˋ)੭*ଘ
    在这里插入图片描述
    在这里插入图片描述
  • 实现代码
#include <iostream>
#include <math.h>
#define N 50
using namespace std;
int D[25][25][25] = {0};

int w(int a, int b, int c)
{
	if (a <= 0 || b <= 0 || c <= 0)
		return 1;
	else if (a > 20 || b > 20 || c > 20)
		return w(20, 20, 20);
	else if (a < b && b < c)
	{
		if (D[a][b][c - 1] == 0)
			D[a][b][c - 1] = w(a, b, c - 1);
		if (D[a][b - 1][c - 1] == 0)
			D[a][b-1][c - 1] = w(a, b-1, c - 1);
		if (D[a][b - 1][c] == 0)
			D[a][b - 1][c] = w(a, b - 1, c);
		D[a][b][c] = D[a][b][c - 1] + D[a][b - 1][c - 1] - D[a][b - 1][c];
		return D[a][b][c];
	}
	else
	{
		if (D[a-1][b][c] == 0)
			D[a-1][b][c] = w(a-1, b, c);
		if (D[a - 1][b - 1][c] == 0)
			D[a - 1][b - 1][c] = w(a - 1, b - 1, c);
		if (D[a-1][b][c-1] == 0)
			D[a-1][b][c-1] = w(a - 1, b, c-1);
		if (D[a-1][b - 1][c-1] == 0)
			D[a-1][b - 1][c-1] = w(a-1, b - 1, c-1);
		D[a][b][c] = D[a-1][b][c] + D[a-1][b - 1][c] + D[a-1][b][c-1] - D[a-1][b-1][c-1];
		return D[a][b][c];
	}
}

int main()
{
	int result, a, b, c, A[N] = { 0 }, B[N] = { 0 }, C[N] = { 0 }, i = 0;
	do
	{
		cin >> a >> b >> c;
		A[i] = a;
		B[i] = b;
		C[i] = c;
		i++;
	} while (a != -1 || b != -1 || c != -1);
	for (int j = 0; j < i-1; j++)
	{
		result = w(A[j], B[j], C[j]);
		cout << "w(" << A[j] << ", " << B[j] << ", " << C[j] << ") = "<<result<<endl;
	}
	return 0;
}
  • 后记:这个题hin有意思! 因为可能造成大量的重复运算,会导致递归过程无限多次,所以需要采取措施来减少多次重复的无意义递归。这里方法是设置一个稍大于20的三维数组(题目中大于20的数会递归为20),然后每一次运算都把w(a, b, c)的结果存在三维数组里。下次再碰见时,就直接调用不用再重复运算啦!记忆化搜索~
  • P1014 Cantor表
    在这里插入图片描述
  • 实现代码
#include <iostream>
#include <math.h>
using namespace std;
int main()
{
	int N,count=1,x=0,y=0;
	cin >> N;
	while(count<N)
	{
		if (y == 0)
		{
			x++;
			count++;
			if (count == N)
			{
				cout << (y + 1) << "/" << (x + 1) << endl;
				return 0;
			}
			while (count<N && x != 0)
			{
				x--;
				y++;
				count++;
			}
			if (count == N)
			{
				cout << (y + 1) << "/" << (x + 1) << endl;
				return 0;
			}
			if (x == 0)
			{
				y++;
				count++;
				if (count == N)
				{
					cout << (y + 1) << "/" << (x + 1) << endl;
					return 0;
				}
				while (count < N && y != 0)
				{
					x++;
					y--;
					count++;
				}
				if (count == N)
				{
					cout << (y + 1) << "/" << (x + 1) << endl;
					return 0;
				}
			}
		}
	}
}
  • 后记:重点是找规律!首先要弄清楚什么是Z字形编号,然后在草稿纸画一画编号和每个数的位置的关系,以及数的大小和位置的关系,很快就写出来啦~
    (草稿图如下:)在这里插入图片描述
  • P1022 计算器的改良
  • 在这里插入图片描述
  • 实现代码
#include <iostream>
#include <math.h>
#include <stdio.h>
#include<iomanip>
using namespace std;

int isletter(char a)
{
	if ((a >= 'a' && a <= 'z' )|| (a >= 'A' && a <= 'Z'))
		return 1;
	else
		return 0;
}

int main()
{
	char equation[50], x;
	gets(equation);
	int i = 0, afterequal = 0, isplus = 1;
	double num_now = 0, num_1 = 0, num_x = 0;
	double result;
	while (equation[i] != '\0')
	{
		if (afterequal == 0)
		{
			if (isletter(equation[i]))
			{
				x = equation[i];
				if (isplus)
				{
					num_x += num_now;
				}
				else
				{
					num_x -= num_now;
				}
				if (num_now == 0)
					num_x += 1;
				num_now = 0;
			}
				if (equation[i] == '+' || equation[i] == '-')
				{
					if (equation[i] == '+')
					{
						if (isplus)
						{
							num_1 += num_now;
							num_now = 0;
						}
						else
						{
							num_1 -= num_now;
							num_now = 0;
						}
						isplus = 1;
					}
					else
					{
						if (isplus)
						{
							num_1 += num_now;
							num_now = 0;
						}
						else
						{
							num_1 -= num_now;
							num_now = 0;
						}
						isplus = 0;
					}
				}
			if (equation[i] == '=')
			{
				afterequal = 1;
				if (isplus)
				{
					num_1 += num_now;
				}
				else
				{
					num_1 -= num_now;
				}
				num_now = 0;
				isplus = 1;
			}
		}
		else
		{
			if (isletter(equation[i]))
			{
				x = equation[i];
				if (isplus)
				{
					num_x -= num_now;
				}
				else
				{
					num_x += num_now;
				}
				if (num_now == 0)
					num_x += 1;
				num_now = 0;
			}
				if (equation[i] == '+' || equation[i] == '-')
				{
					if (equation[i] == '+')
					{
						if (isplus)
						{
							num_1 -= num_now;
							num_now = 0;
						}
						else
						{
							num_1 += num_now;
							num_now = 0;
						}
						isplus = 1;
					}
					else
					{
						if (isplus)
						{
							num_1 -= num_now;
							num_now = 0;
						}
						else
						{
							num_1 += num_now;
							num_now = 0;
						}
						isplus = 0;
					}
				}
		}
		if (equation[i] >= '0' && equation[i] <= '9')
		{
			num_now = num_now * 10 + equation[i] - 48;
		}
		i++;
	}
	if (isplus)
	{
		num_1 -= num_now;
	}
	else
		num_1 += num_now;
	num_1 *= -1;
	result = double(num_1/num_x);
	if (result == -0.0)
		printf("%c=0.000", x);
	else
		printf("%c=%.3f", x, result);
	return 0;
}
  • 后记:我写的有点长。。尤其是看了讨论区别的大佬的解析过后,他们为什么能写的这么短!!(;´д`)ゞ
    这道题主要是分情况讨论:
  1. 等号左边和等号右边的加减处理

  2. 未知数的系数合并(带符号)

  3. 常数项的系数合并(带符号)

    然后最后输出也有点坑,因为会出现-0.0的情况,通不过测试点,必须特例处理将-0.0变为0.000输出。另外,因为我习惯用cout输出,规定输出3个小数点时用setprecision是不行的,因为最后的0会被省略。学习用printf来输出~

  • P1307 数字反转
  • 后记:这个就不贴题目和代码了,比较简单~

于是以上就是我在新手村做的题目,逻辑比较简单,重点考察基本的代码编写能力和一些边角问题处理。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值