入门语法题目精讲

P5710数的性质

对于本题,我们定义两个bool类型的变量分别代表数字是否满足性质1和2

即:

bool is1=x%2==0;
bool is2=(x>4 && x<=12);

这样两个变量就可以代表是否满足性质1跟2了

那么小A其实就是两个值\(&&\)的结果

Uim就是两个值\(||\)的结果

小B就是会比较麻烦,就是第一个和第二个取\(!\)之后再\(&&\)的结果\(||\)上第一个取\(!\)和第二个\(&&\)之后的结果,文字有点难以理解,主要看代码

正妹就是两个同时取\(!\)之后再\(&&\)的结果

代码如下

#include<iostream>
using namespace std;
int main()
{
	int x;
	cin>>x;
	bool is1=x%2==0;
	bool is2=(x>4 && x<=12);
	bool ans1=is1 && is2;
	bool ans2=is1 || is2;
	bool ans3=(is1 && (!is2)) || ((!is1) && is2) ;
	bool ans4=(!is1) && (!is2);
	cout<<ans1<<" "<<ans2<<" "<<ans3<<" "<<ans4;
	return 0;
} 

P5715三位数排序

本题并不难,需要注意的点是要学会交换两个变量的值,具体过程如下:

int a,b;
cin>>a>>b;
int t=a;
a=b;
b=t;
cout<<a<<b;

在上述代码,我们用了第三个变量存下了a的值,这样在a赋成b的值之后还能通过t将原本a的值赋给b,从而达到交换值的效果

如果没有这个第三变量存a的值,那么在把a赋成b的值之后原本a的值就消失了,两个变量的值都变成了原本b的值,从而无法实现交换的效果

那么在学会了交换之后,这道题就是把最大的值换到最后,中间的值换到中间,最小值换到前面就行了,实现如下:

#include<iostream>
using namespace std;
int main()
{
	int a,b,c;
	cin>>a>>b>>c;
	if(a>b)
	{
		int t=a;
		a=b;
		b=t;
	}
	if(a>c)
	{
		int t=a;
		a=c;
		c=t;
	}
	if(b>c)
	{
		int t=b;
		b=c;
		c=t;
	}
	cout<<a<<" "<<b<<" "<<c;
	return 0;
}

上述代码中,一开始在a>b时我们交换两值,所以此时a一定小于等于b,同理又在a>c时交换两值,又保证了a一定小于等于b,所以此时a一定是最小的

此时再用一样的方法保证了b小于等于c,所以三个数一定是排好序的

需要注意的时,如果你写成了:

#include<iostream>
using namespace std;
int main()
{
	int a,b,c;
	cin>>a>>b>>c;
	if(a>b)
	{
		int t=a;
		a=b;
		b=t;
	}
	if(b>c)
	{
		int t=b;
		b=c;
		c=t;
	}
	if(a>c)
	{
		int t=a;
		a=c;
		c=t;
	}
	
	cout<<a<<" "<<b<<" "<<c;
	return 0;
}

那么你将无法通过本题,为什么呢?

我们推一下,刚开始第一个if保证了a小于等于b,第二个if保证了b小于等于c,第三个if保证了a小于等于c,看似没有问题

但是在第二个if的时候,b的值有可能进行了交换,那么b的值就变了,此时a就不一定小于等于b,那么就不一定满足题意了,所以会发生错误

大家在设计算法的时候一定要注意这种逻辑错误

此外,我们补充一个函数\(swap\),作用是交换两个变量的值,所以,这题的代码就会缩减很多,具体如下:

#include<iostream>
using namespace std;
int main()
{
	int a,b,c;
	cin>>a>>b>>c;
	if(a>b)
	{
		swap(a,b); 
	}
	if(a>c)
	{
		swap(a,c);
	}
	if(b>c)
	{
		swap(b,c);
	}
	cout<<a<<" "<<b<<" "<<c;
	return 0;
}

P1424 小鱼的航程(改进版)

首先,考虑每七天是一个周期,每个周期游1250,所以答案完整周期部分是\(1250*(n/7)\)

然后考虑从当前天到第一个周一的不满一周的天数,显然当前天到到第一个周一的天数为\(8-x\),由于周末无用,所以游的天数是(6-x),小于0的时候按0处理

然后再考虑最后不到一周的天数,先减去前面到第一个周一的天数,即\(8-x\),然后就是最后不满一周的天数了,如果超过五天就说明存在周末,按五天计算即可

所以三部分相加便是答案,实现如下:

#include<iostream>
using namespace std;
int main()
{
	int x,n;
	cin>>x>>n;
	int pre=6-x; 
	if(pre<0)
	{
		pre=0;
	} 
	n-=8-x;
	int back=n%7;
	if(back>5) 
	{
		back=5;
	}
	int ans=pre*250+n/7*1250+back*250;
	cout<<ans; 
	return 0;
}

在这里,我们再学两个新的函数,分别是\(max()\)和\(min()\)

两个函数的参数都会有两个,然后如同名字一样,\(max(x,y)\)会得到\(x\)和\(y\)中较大的一个

同理,\(min\)函数会得到较小的一个

在本题中,我们在\(pre\)小于0的时候设成0,其实就是取0和\(pre\)中较大的那个值

\(back\)则是5和\(back\)中较小的那个值

所以,本题的代码可以改写成:

#include<iostream>
using namespace std;
int main()
{
	int x,n;
	cin>>x>>n;
	int pre=max(0,6-x); 
	n-=8-x;
	int back=min(n%7,5);
	int ans=pre*250+n/7*1250+back*250;
	cout<<ans; 
	return 0;
}

代码就简短了许多


P1909 [NOIP 2016 普及组] 买铅笔

对于本题,要花费最少,所以我们只需要分别算出三种包装所需要的价钱,然后输出最小值就行了

那么唯一的问题就是怎么算出来每种的价钱

显然只需要算出每种包装需要多少,然后乘价格就行了

但是我们发现如果直接除,在不能除尽的情况下,c++的整除会是向下取整的,所以我们是差一包的,所以要特判有余数的时候多一包

如果只是这样那么这道题根本不算经典!

在这里,我们要讲的其实是向上取整

在c++中,a除以b向上取整可以写成这样:

int x=(a+b-1)/b;

为什么这样是向上取整呢?

让我们来拆解一下

我们先设\(a=b*t+m\)

那么上述式子就变成了\((b*t+m+b-1)/b\)

如果\(m\)等于0

那么就是\((b*t+b-1)/b\) 显然,向下取整之后会是t

那么就跟直接整除是一样的,都是t

如果\(m\)大于0

原式可以写成\((b*(t+1)+m-1)/b\)

由于\(m\)是\(a/b\)的余数,所以必定小于\(b\),那么\(m-1\)必定小于\(b\),所以向下取整之后得到\(t+1\)

所以在在\(a/b\)余零的时候该式子得到\(t\),其余情况得到\(t+1\),我们就实现了向上取整的效果

所以,本题代码实现如下:

#include<iostream>
using namespace std;
int main()
{
	int n;
	cin>>n;
	int num,v;//num为每包数量,v为价格 
	cin>>num>>v;
	int ans1=(n+num-1)/num*v;//算出第一种所需价钱 
	cin>>num>>v;//输入第二种的数量和价格 
	int ans2=(n+num-1)/num*v;//算出第二种所需的价钱 
	cin>>num>>v;//同上
	int ans3=(n+num-1)/num*v;
	cout<<min(ans1,min(ans2,ans3));//输出最小的
	return 0; 
} 


P5705 【深基2.例7】数字反转

可以发现这道题前面的几道题都是字符变量的练习题,这道题确实浮点数

但其实,这道题也是字符变量的练习题

本题的关键点在于我们不能把输入看成一个浮点数,一个不小于一百,小于一千的一位浮点数,其实是由四个数字和一个小数点组成

所以我们把输入看成五个字符,然后倒着输出就行

实现如下:

#include<iostream>
using namespace std;
int main()
{
	char a,b,c,d,e;
	cin>>a>>b>>c>>d>>e;
	cout<<e<<d<<c<<b<<a;
	return 0;
}
posted @ 2026-10-12 20:36  罗小菜  阅读(6)  评论(0)    收藏  举报