栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

2022.7.25优解整理

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

2022.7.25优解整理

 ,每次v1. 

# [NOIP2001 普及组] 数的计算

## 题目描述

我们要求找出具有下列性质数的个数(包含输入的正整数 $n$)。

先输入一个正整数 $n$($n le 1000$),然后对此正整数按照如下方法进行处理:

1. 不作任何处理;

2. 在它的左边拼接一个正整数,但该正整数不能超过原数,或者是上一个被拼接的数的一半;

3. 加上数后,继续按此规则进行处理,直到不能再加正整数为止。

## 输入格式

一行,一个正整数 $n$($n le 1000$)。

## 输出格式

一个整数,表示具有该性质数的个数。

## 样例 #1

### 样例输入 #1

```
6
```

### 样例输出 #1

```
6
```

## 提示

**【样例解释】**

满足条件的数为:$6$,$16$,$26$,$126$,$36$,$136$。

**【题目来源】**

NOIP 2001 普及组第一题

我们以4为例子来进行说明

4后面可以跟上1,2组成14,24

14后面跟不了,24可以跟上1组成124

再加上4本身就可以得到4的种类

即 14,24,124,4

而我们只要算出1,2的种类就可以加起来得到4的种类

因此,我们得到

f[1]=1
f[2]=2=f[1]+1
f[3]=2=f[1]+1
f[4]=4=f[1]+f[2]+1
f[5]=4=f[1]+f[2]+1

using namespace std;
int n;
int f[1001];//存每一位数的种类
int main(){
    cin>>n;
    for(int i=1;i<=n;i++){ //1-n的递推
        for(int j=1;j<=i/2;j++){
            f[i]+=f[j]; //每一位叠加,递推走起
        }
        f[i]++; //加上本身
    }
    cout< 

 2.

# [NOIP1998 提高组] 车站

## 题目描述

火车从始发站(称为第 $1$ 站)开出,在始发站上车的人数为 $a$,然后到达第 $2$ 站,在第 $2$ 站有人上、下车,但上、下车的人数相同,因此在第 $2$ 站开出时(即在到达第 $3$ 站之前)车上的人数保持为 $a$ 人。从第 $3$ 站起(包括第 $3$ 站)上、下车的人数有一定规律:上车的人数都是前两站上车人数之和,而下车人数等于上一站上车人数,一直到终点站的前一站(第 $(n-1)$ 站),都满足此规律。现给出的条件是:共有 $n$ 个车站,始发站上车的人数为 $a$ ,最后一站下车的人数是 $m$(全部下车)。试问 $x$ 站开出时车上的人数是多少?

## 输入格式

输入只有一行四个整数,分别表示始发站上车人数 $a$,车站数 $n$,终点站下车人数 $m$ 和所求的站点编号 $x$。

## 输出格式

输出一行一个整数表示答案:从 $x$ 站开出时车上的人数。

## 样例 #1

### 样例输入 #1

```
5 7 32 4
```

### 样例输出 #1

```
13
```

## 提示

对于全部的测试点,保证 $1 leq a leq 20$,$1 leq x leq n leq 20$,$1 leq m leq 2 times 10^4$。

本题重点:斐波那契数列。 规律

设第二站上下车人数为b。

经过几步计算,可以得到下表:

显然前两行都与前面的数有关,就猜测第三行也与前面的数有关,于是得到第四行。很明显可以发现第四行a的系数比第三行多11,b的系数比第三行少11。

所以不用管前两行,把第三行直接列出来就行了。方程:

//sum1表示a的系数,sum2表示b的系数
sum1[i]=sum1[i-1]+sum1[i-2]-1;//前两个的和-1
sum2[i]=sum2[i-1]+sum2[i-2]+1;//前两个的和+1
后续

算完这些,b也就能够根据a和m求出来了。

很显然,a*sum1[n-1]+b*sum2[n-1]=ma∗sum1[n−1]+b∗sum2[n−1]=m。

即b=(m-a*sum1[n-1])/sum2[n-1]b=(m−a∗sum1[n−1])/sum2[n−1]。 于是答案就是  a*sum1[x]+b*sum2[x]∗sum1[x]+b∗sum2[x]。

#include
using namespace std;
int sum1[25], sum2[25];
int main() 
{
	int a,n,m,x;
	sum1[2] = 1; sum1[3] = 2;
	cin >> a >> n >> m >> x;
	for (int i = 4; i < n; i++) {
		sum1[i] = sum1[i - 1] + sum1[i - 2] - 1;
		sum2[i] = sum2[i - 1] + sum2[i - 2] + 1;
	}
	int b = (m - a * sum1[n - 1]) / sum2[n - 1];
	cout << a * sum1[x] + b * sum2[x];
	return 0;
}

3.

 

# [NOIP2001 普及组] 最大公约数和最小公倍数问题

## 题目描述

输入两个正整数 $x_0, y_0$,求出满足下列条件的 $P, Q$ 的个数:

1. $P,Q$ 是正整数。

2. 要求 $P, Q$ 以 $x_0$ 为最大公约数,以 $y_0$ 为最小公倍数。

试求:满足条件的所有可能的 $P, Q$ 的个数。

## 输入格式

一行两个正整数 $x_0, y_0$。

## 输出格式

一行一个数,表示求出满足条件的 $P, Q$ 的个数。

## 样例 #1

### 样例输入 #1

```
3 60
```

### 样例输出 #1

```
4
```

## 提示

$P,Q$ 有 $4$ 种:

1. $3, 60$。
2. $15, 12$。
3. $12, 15$。
4. $60, 3$。

对于 $100%$ 的数据,$2 le x_0, y_0 le {10}^5$。

**【题目来源】**

NOIP 2001 普及组第二题

前置知识

  • 最大公约数(即 gcdgcd) 和最小公倍数(即 operatorname{lcm}lcm)的求法。

该题的关键点在于,两个数的积等于它们最大公约数和它们最小公倍数的积。公式表示为 atimes b=gcd(a,b) times operatorname{lcm}(a,b)a×b=gcd(a,b)×lcm(a,b)。设作为答案的两个数为 xx 和 yy,我们要使它们同时满足以下三个条件,并统计这样的 xx 和 yy 的个数(P,QP,Q 含义见题目描述):

  • x times y=P times Qx×y=P×Q
  • gcd(x,y)=Pgcd(x,y)=P
  • operatorname{lcm}(x,y)=Qlcm(x,y)=Q

我们可以枚举 xx,判断是否存在满足条件 11 的整数 yy(即,xx 能否被 P,QP,Q 的积整除)。满足第一个条件后,再分别判断当前的 x,yx,y 是否能够同时满足另外两个条件即可。显然,这种做法会超时。

考虑优化这个程序。我们其实并不需要枚举两次,因为对于不同的 x,yx,y ,交换它们的值一定可以得到另一组与之对应的解。因此,从 11 到 sqrt{Ptimes Q}P×Q​ 枚举一遍,每发现一组答案就将 ansans 的值加上 22 即可。

一组 x,yx,y 有对应解时有条件:x,yx,y 的值不同。如果它们相同,交换后并不能得到与之对应的另一组数。当 x=yx=y 时,易得 x=y=gcd(x,y)=operatorname{lcm}(x,y)x=y=gcd(x,y)=lcm(x,y)。 所以要对此进行特判,若 P,QP,Q 相等,这种情况就存在, ansans 里要减去 11。

一些代码实现技巧:

  • c++ 里有一个自带的求 gcdgcd 的函数叫 __gcd 。upd:现在 NOIP 已经可以使用了。

  • 当积相同且 gcdgcd 相同时,operatorname{lcm}lcm 也一定相同,因此只需判断是否满足一、二两个条件即可。

AC代码:(应该是目前最短的)

#include
using namespace std;
long long m,n,ans;
int main(){
	cin>>m>>n;
	if(m==n) ans--;
	n*=m;//把两数的积存入n中 
	for(long long i=1;i<=sqrt(n);i++){
		if(n%i==0&&__gcd(i,n/i)==m) ans+=2;
	}
	cout<

评论区常见问题统一回答:

Q:gcdgcd 是什么?
A:是“最大公约数”的缩写。同理,operatorname{lcm}lcm 是“最小公倍数”的缩写。

Q:代码中为什么枚举到 sqrt{n}n​?
A:前文提到,我们要避免重复,因此循环时只算 xle yx≤y 的情况。当 x=yx=y 时,x=sqrt{n}x=n​。再使 xx 变大就会使 x>yx>y 了,计算会重复。

 

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/1032377.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号