C++刷题 【入门3】循环结构

【入门3】循环结构

虽然计算机可以在短时间批量处理成千上万条指令,但是不少问题中有许多规律性的重复操作,比如说计算几百个学生的平均分,或者对上万人的名单进行排序。仅使用顺序或者分支结构,对每一步操作都写出对应的语句是不可能的;但可以使用循环语句让计算机反复执行类似的任务。

本章将会介绍循环结构程序设计,同时前面的内容也会进一步的巩固。学完这一章,读者可以初步感受到计算机高效解决问题的能力。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-7RjWTXd5-1680532688470)(2023-03-22-15-52-46.png)]

【深基4.例4】一尺之棰

# 【深基4.例4】一尺之棰

## 题目描述

《庄子》中说到,“一尺之棰,日取其半,万世不竭”。第一天有一根长度为 $a$ 的木棍,从第二天开始,每天都要将这根木棍锯掉一半(每次除 $2$,向下取整)。第几天的时候木棍的长度会变为 $1$?

## 输入格式

输入一个正整数 $a$,表示木棍长度。

## 输出格式

输出一个正整数,表示要第几天的时候木棍长度会变为 $1$。

## 样例 #1

### 样例输入 #1

```
100
```

### 样例输出 #1

```
7
```

## 提示

数据保证,$1 \le a\le 10^9$。\
while 循环,每次除以 
2
2,如果到一了,退出循环。

code:

# include <iostream>
# include <stdio.h>

using namespace std;
int a, ans = 1;

int main () {
	scanf ("%d", &a);
	while (a > 1) {
		ans++; 
		a /= 2;
	}
	cout << ans << endl;
	return 0;
}

【深基4.例6】数字直角三角形

# 【深基4.例6】数字直角三角形

## 题目描述

给出 $n$,请输出一个直角边长度是 $n$ 的数字直角三角形。所有数字都是 $2$ 位组成的,如果没有 $2$ 位则加上前导 $0$。

## 输入格式

输入一个正整数 $n$。

## 输出格式

输出如题目要求的数字直角三角形。

## 样例 #1

### 样例输入 #1

```
5
```

### 样例输出 #1

```
0102030405
06070809
101112
1314
15
```

## 提示

数据保证,$1\le n\le13$。

这题还是有点技巧的

可以看出要输出
�
(+
1
)
a(a+1)个数

每行输出a,a-1……,1个数

所以用i记录现在要输出什么

j记录在第几列

j>a之后就换行

输出是注意所有数字都是 2 位组成的即可

std:
#include <iostream>
#include <algorithm>

using namespace std;

int a,b;

int main()
{
    int i,j,k;
    cin>>a;
    b=a;
    a=a*(a+1)/2;
    j=1;
    i=1;
    while(i<=a)
    {
        if(i<10)
        {
            cout<<0<<i;
        }
        else
        {
            cout<<i;
        }
        i++;
        j++;
        if(j>b)
        {
            b--;
            j=1;
            cout<<endl;
        }
    }
    return 0;
}

解法2

这道题不坑,也不难

唯一不好解决的就是

所有数字都是 2 位组成的,如果没有 2 位则加上前导 0。
这里介绍一种巧妙又方便的方法:
printf("%02d",变量名);
下面上代码:

#include<bits/stdc++.h>
using namespace std;
int main(){
	int n,t=0,a;//t表示当前需要输出的数字
	cin>>n;
	a=n;//a控制列数
	for(int i=0;i<n;i++){//n行
		for(int j=0;j<a;j++){//每行a列
			t++;//需要输出的数+1
 //这里必须先加再输出,不然好像会出错
 //因为这里先加再输出,所以t需要初始化为0 
			printf("%02d",t);//高级方法
		}
		a--;//每输出一行,减少一列
		cout<<endl;//换行
	}
	return 0;//完美结束
}

[NOIP1998 普及组] 阶乘之和

# [NOIP1998 普及组] 阶乘之和

## 题目描述

用高精度计算出 $S = 1! + 2! + 3! + \cdots + n!$($n \le 50$)。

其中 `!` 表示阶乘,定义为 $n!=n\times (n-1)\times (n-2)\times \cdots \times 1$。例如,$5! = 5 \times 4 \times 3 \times 2 \times 1=120$。

## 输入格式

一个正整数 $n$。

## 输出格式

一个正整数 $S$,表示计算结果。

## 样例 #1

### 样例输入 #1

```
3
```

### 样例输出 #1

```
9
```

## 提示

**【数据范围】**

对于 $100 \%$ 的数据,$1 \le n \le 50$。

**【其他说明】**

注,《深入浅出基础篇》中使用本题作为例题,但是其数据范围只有 $n \le 20$,使用书中的代码无法通过本题。

如果希望通过本题,请继续学习第八章高精度的知识。


C_Z_C
更新时间:2019-08-18 20:25:27
在 Ta 的博客查看
本蒟的第一篇题解,不要问我为什么要发这篇题解,昨天用了半天才写完了这篇橙题代码,大佬勿喷。

**本蒟的思路就是高精乘+高精加,就是把高精乘的模板套上去接着套高精加的模板,b=c=i的阶乘。**

话不多说,直接上代码:

#include<iostream>
#include<cstring>
using namespace std;
int n,a[90],b[90],c[90],f[90],d=0,len_a,len_b=1,len_c=1,len_ans,m=1;
string s;
int main(){
    cin>>n;
    b[0]=1; //初始化
    for(int i=1;i<=n;i++){ //计算i的阶乘,已经算好了i-1的阶乘
        len_a=0; //i的长度
        int p=i;
        while(p>0){ //把i存进a数组
            a[len_a++]=p%10;
            p/=10;
        }
        for(int j=0;j<len_a;j++) //计算a*b(i*(i-1)的阶乘),即i的阶乘,看不懂的网上查,我也不知道为什么
            for(int k=0;k<=len_b;k++)
                c[j+k]+=a[j]*b[k];
        for(int j=0;j<len_c;j++) //需要进位的就进位
            if(c[j]>9) c[j+1]+=c[j]/10,c[j]%=10;
        if(c[len_c]) len_c++; //看最高位要不要进位
        len_ans=len_b,len_b=len_c,m=max(m,len_c); //把len_b赋值给len_ans,修改len_b的值,m为i阶乘的长度,看有没有进位
        for(int k=len_c-1;k>=0;k--) b[k]=c[k]; //把c存进b数组,即存进i的阶乘,下次循环b为i-1的阶乘
        len_c=len_a+len_ans;
        memset(c,0,sizeof(c)); //清零c数组,准备计算下个阶乘
        for(int j=0;j<m;j++){ //高精加,直接套模板
            f[j]+=b[j];
            if(f[j]>9) f[j+1]+=f[j]/10,f[j]%=10; //进位,注意不要写成f[j+1]++,f[j]-=10;就因为这里wa了一个点
        }
    }
    while(!f[m]&&m>0) m--; //去掉首导零
    for(int i=m;i>=0;i--) cout<<f[i]; //倒序输出
    return 0; //圆满结束
}


[NOIP2013 普及组] 计数问题

# [NOIP2013 普及组] 计数问题

## 题目描述

试计算在区间 $1$ 到 $n$ 的所有整数中,数字 $x$($0\le x\le9$)共出现了多少次?例如,在 $1$ 到 $11$ 中,即在 $1,2,3,4,5,6,7,8,9,10,11$ 中,数字 $1$ 出现了 $4$ 次。

## 输入格式

$2$ 个整数 $n,x$,之间用一个空格隔开。

## 输出格式

$1$ 个整数,表示 $x$ 出现的次数。

## 样例 #1

### 样例输入 #1

```
11 1
```

### 样例输出 #1

```
4
```

## 提示

对于 $100\%$ 的数据,$1\le n\le 10^6$,$0\le x \le 9$。

#include<iostream>
using namespace std;
int main()
{
    long long n,i,x,b,c,t=0;
    cin>>n>>x;//输入范围与要查的数字;
    for(i=1;i<=n;i++)//一到n进行循环;
    {
        b=i;//为了不改变i的值,就把i赋值给一个数;
        while(b!=0)//如果b不等于0,继续循环;
        {
            c=b%10;//求是否是x,是的话计数器加一;
            b=b/10;//求下一个数字是否为x;
            if(c==x) t++;计数器加一;
        }
    }
    cout<<t<<endl;//输出计数器的数字;
    return 0;//结束
}

方法2

用的最笨的办法,一步一步的循环解的思路,希望有更优的解题思路,以供参考

#include <stdio.h>
int main(){
    int a,b,j=0;
    scanf("%d %d",&a,&b);
    for(int i=1;i<=a;i++){
        int d=i;
        while(d>0){
            int c=d%10;
            d=d/10;
            if(c==b){
                j++;
            }
        }
    }
    printf("%d",j);
    return 0;
}


方法3


John_Nash 
更新时间:2016-02-08 20:39:46
在 Ta 的博客查看
这题是noip2013普及组第一题,难度肯定不大,nlog10n的算法不难想出,这里不再说明。

在真正的比赛中,只要想到能ac的算法就可以,但是在练习中还是要锻炼自己的思维,多想想更优的算法。

不难发现,即使不用计算机,答案也很容易求出,如:

n=728,x=7

可以按照这样的思路:

个位7:737,17,...,727

十位7:7070~79,170~179,...,670~679

百位7:29700~728

答案是172

这样,就不难写出log10n的算法,这是一个巨大的改进!


#include<iostream>
#include<cstdio>
using namespace std;
int main(){
    int n,x,m=1,ans=0;
    scanf("%d%d",&n,&x);
    while(m<=n){
        int a=n/(m*10),b=n/m%10,c=n%m; //a,b,c为n的三部分,求哪一位x的个数,b就为那一位数,a为b左边的数,c为b右边的数,如求1~728中十位7的个数,则a=7,b=2,c=8
        if(x){
            if(b>x) ans+=(a+1)*m; //如果b>x,说明有(a+1)*m个x(如求1~728中个位7的个数,则为(72+1)*1=73)
            if(b==x) ans+=a*m+c+1; //如果b=x,说明有a*m+c+1个x(如求1~728中百位7的个数,则为0*100+28+1=29)
            if(b<x) ans+=a*m; //如果b<x,说明有a*m个x(如求1~728中十位7的个数,则为7*10个)
        }
        else{ //x=0的情况和x!=0的情况有所不同
            if(b) ans+=a*m;
            else ans+=(a-1)*m+c+1;
        }
        m*=10;
    }
    printf("%d\n",ans);
    return 0;
}

[NOIP2002 普及组] 级数求和

https://www.luogu.com.cn/problem/P1035
# [NOIP2002 普及组] 级数求和

## 题目描述

已知:$S_n= 1+\frac{1}{2}+\frac{1}{3}+…+\frac{1}{n}$。显然对于任意一个整数 $k$,当 $n$ 足够大的时候,$S_n>k$。

现给出一个整数 $k$,要求计算出一个最小的 $n$,使得 $S_n>k$。

## 输入格式

一个正整数 $k$。

## 输出格式

一个正整数 $n$。

## 样例 #1

### 样例输入 #1

```
1
```

### 样例输出 #1

```
2
```

## 提示

**【数据范围】**

对于 $100\%$ 的数据,$1\le k \le 15$。

**【题目来源】**

NOIP 2002 普及组第一题
https://www.luogu.com.cn/problem/solution/P1035
1.模拟

这种做法的思路是枚举
n从1开始,直到>
Sn>k结束,只需要一个循环即可实现。

代码:

#include<cstdio>
int main() {
    int k,n=0;
    scanf("%d",&k);
    for(double Sn=0;Sn<=k;++n,Sn+=1.0/n);
    printf("%d",n);
    return 0;
}


2.数论(调和级数)

关于调和级数的姿势,点这里。

已知
�
�
=
1
+
1
/
2
+
1
/
3
+
.
.
.
+
1
/=
∑
�
=
11
�
Sn=1+1/2+1/3+...+1/n=∑ 
k=1
n
​
  
k
1
​
 。

明显地,
�
�
Sn为第
�
n个调和数。

欧拉推导过求调和级数有限多项和的表达式为
∑
�
=
11=
ln
⁡
(+
1
)
+
�
∑ 
k=1
n
​
  
k
1=ln(n+1)+γ,我们拿过来用即可。(
�
γ约等于0.5772156649)

我们需要满足
�
�
>
�
Sn>k,即满足
ln
⁡
(+
1
)
+>ln(n+1)+γ>k,化简得
�
>
�
�
−
�
−
1
n>e 
k−γ
 −1。

我们只需求满足上式的最小的
�
n,所以
�
=
�
�
−
�
+
0.5
n=e 
k−γ
 +0.5(四舍五入),即模拟做法的时间复杂度为
�
(
�
�
−
�
)
O(e 
k−γ
 )。

关于
�
γ(欧拉-马歇罗尼常数)的姿势,点这里。

代码:

#include<cstdio>
#include<cmath>
const double gamma=0.5772156649;
int main() {
    int k,n;
    scanf("%d",&k);
    n=exp(k-gamma)+0.5;
    printf("%d",n);
    return 0;
}

P2669 [NOIP2015 普及组] 金币

# [NOIP2015 普及组] 金币

## 题目背景

NOIP2015 普及组 T1

## 题目描述

国王将金币作为工资,发放给忠诚的骑士。第一天,骑士收到一枚金币;之后两天(第二天和第三天),每天收到两枚金币;之后三天(第四、五、六天),每天收到三枚金币;之后四天(第七、八、九、十天),每天收到四枚金币……;这种工资发放模式会一直这样延续下去:当连续 $n$ 天每天收到 $n$ 枚金币后,骑士会在之后的连续 $n+1$ 天里,每天收到 $n+1$ 枚金币。

请计算在前 $k$ 天里,骑士一共获得了多少金币。

## 输入格式

一个正整数 $k$,表示发放金币的天数。

## 输出格式

一个正整数,即骑士收到的金币数。

## 样例 #1

### 样例输入 #1

```
6
```

### 样例输出 #1

```
14
```

## 样例 #2

### 样例输入 #2

```
1000
```

### 样例输出 #2

```
29820
```

## 提示

**【样例 1 说明】**

骑士第一天收到一枚金币;第二天和第三天,每天收到两枚金币;第四、五、六天,每天收到三枚金币。因此一共收到 $1+2+2+3+3+3=14$ 枚金币。


对于 $100\%$ 的数据,$1\le k\le 10^4$。
#include<iostream>
using namespace std;
int main()
{
	int a,b=0,c=1,i;//a为天数,b为金币,c为每天比原来每天多获得的金币数 
	cin>>a;
	for(i=1;i<=a;i++)
		a-=i,b+=c*c,c++;//金币每天加上c的2次方,天数当然要减i了
	cout<<b+a*c;//最后算上剩余的a乘加的最多一次的c
	return 0;
}
#include<iostream>
using namespace std;
int main(){
int a,b=0,c=1,i;cin>>a;for(i=1;i<=a;i++)a-=i,b+=c*c,c++;cout<<b+a*c;//挤在了一行上
}
#include <iostream>	
//反对万能头!
using namespace std;
int n,q,c,s;
//n是有多少天
//s是获得的金币总量
//c是每天能获得的金币数
//q表示往后数q天,获得的金币都是c个
int main()
{
    cin>>n;
    c=q=1;	//第一天(往后的一天),获得1个金币
    for(int i=1;i<=n;i++)	//要发n天金币
    {
        s+=c;	//累加
        q--;	//已经发了一天
        if(q==0)	//要更新数据
        {
            c++;	//每天获得金币的数量+1
            q=c;	//根据题意,以后的c天都是c个金币,q就是c
        }
    }
    cout<<s;	//输出
    return 0;	//THE END
}

P3383 【模板】线性筛素数

# 【模板】线性筛素数

## 题目背景

本题已更新,从判断素数改为了查询第 $k$ 小的素数  
提示:如果你使用  `cin` 来读入,建议使用 `std::ios::sync_with_stdio(0)` 来加速。

## 题目描述

如题,给定一个范围 $n$,有 $q$ 个询问,每次输出第 $k$ 小的素数。

## 输入格式

第一行包含两个正整数 $n,q$,分别表示查询的范围和查询的个数。

接下来 $q$ 行每行一个正整数 $k$,表示查询第 $k$ 小的素数。

## 输出格式

输出 $q$ 行,每行一个正整数表示答案。

## 样例 #1

### 样例输入 #1

```
100 5
1
2
3
4
5
```

### 样例输出 #1

```
2
3
5
7
11
```

## 提示

【数据范围】  
对于 $100\%$ 的数据,$n = 10^8$,$1 \le q \le 10^6$,保证查询的素数不大于 $n$。

Data by NaCly\_Fish.

https://www.luogu.com.cn/problem/solution/P3383

网上有很多关于筛素数的帖子、博文,可以自学一下。

P1217 [USACO1.5]回文质数 Prime Palindromes

# [USACO1.5]回文质数 Prime Palindromes

## 题目描述

因为 $151$ 既是一个质数又是一个回文数(从左到右和从右到左是看一样的),所以 $151$ 是回文质数。

写一个程序来找出范围 $[a,b] (5 \le a < b \le 100,000,000)$(一亿)间的所有回文质数。

## 输入格式

第一行输入两个正整数 $a$ 和 $b$。

## 输出格式

输出一个回文质数的列表,一行一个。

## 样例 #1

### 样例输入 #1

```
5 500
```

### 样例输出 #1

```
5
7
11
101
131
151
181
191
313
353
373
383
```

## 提示

Hint 1: Generate the palindromes and see if they are prime.

提示 1: 找出所有的回文数再判断它们是不是质数(素数).


Hint 2: Generate palindromes by combining digits properly. You might need more than one of the loops like below.

提示 2: 要产生正确的回文数,你可能需要几个像下面这样的循环。


题目翻译来自NOCOW。

USACO Training Section 1.5


产生长度为 $5$ 的回文数:

```cpp
for (d1 = 1; d1 <= 9; d1+=2) {    // 只有奇数才会是素数
     for (d2 = 0; d2 <= 9; d2++) {
         for (d3 = 0; d3 <= 9; d3++) {
           palindrome = 10000*d1 + 1000*d2 +100*d3 + 10*d2 + d1;//(处理回文数...)
         }
     }
 }

```

方法1(打表)

打表
哈哈哈哈真爽

#include<cstdio>
#include<cstring>
using namespace std;
int a,b,db[800]={0,2,3,5,7,11,101,131,151,181,
191,313,353,373,383,727,757,787,797,
919,929,10301,10501,10601,11311,11411,12421,12721,
12821,13331,13831,13931,14341,14741,15451,15551,16061,
16361,16561,16661,17471,17971,18181,18481,19391,19891,
19991,30103,30203,30403,30703,30803,31013,31513,32323,
32423,33533,34543,34843,35053,35153,35353,35753,36263,
36563,37273,37573,38083,38183,38783,39293,70207,70507,
70607,71317,71917,72227,72727,73037,73237,73637,74047,
74747,75557,76367,76667,77377,77477,77977,78487,78787,
78887,79397,79697,79997,90709,91019,93139,93239,93739,
94049,94349,94649,94849,94949,95959,96269,96469,96769,
97379,97579,97879,98389,98689,1003001,1008001,1022201,1028201,
1035301,1043401,1055501,1062601,1065601,1074701,1082801,1085801,1092901,
1093901,1114111,1117111,1120211,1123211,1126211,1129211,1134311,1145411,
1150511,1153511,1160611,1163611,1175711,1177711,1178711,1180811,1183811,
1186811,1190911,1193911,1196911,1201021,1208021,1212121,1215121,1218121,
1221221,1235321,1242421,1243421,1245421,1250521,1253521,1257521,1262621,
1268621,1273721,1276721,1278721,1280821,1281821,1286821,1287821,1300031,
1303031,1311131,1317131,1327231,1328231,1333331,1335331,1338331,1343431,
1360631,1362631,1363631,1371731,1374731,1390931,1407041,1409041,1411141,
1412141,1422241,1437341,1444441,1447441,1452541,1456541,1461641,1463641,
1464641,1469641,1486841,1489841,1490941,1496941,1508051,1513151,1520251,
1532351,1535351,1542451,1548451,1550551,1551551,1556551,1557551,1565651,
1572751,1579751,1580851,1583851,1589851,1594951,1597951,1598951,1600061,
1609061,1611161,1616161,1628261,1630361,1633361,1640461,1643461,1646461,
1654561,1657561,1658561,1660661,1670761,1684861,1685861,1688861,1695961,
1703071,1707071,1712171,1714171,1730371,1734371,1737371,1748471,1755571,
1761671,1764671,1777771,1793971,1802081,1805081,1820281,1823281,1824281,
1826281,1829281,1831381,1832381,1842481,1851581,1853581,1856581,1865681,
1876781,1878781,1879781,1880881,1881881,1883881,1884881,1895981,1903091,
1908091,1909091,1917191,1924291,1930391,1936391,1941491,1951591,1952591,
1957591,1958591,1963691,1968691,1969691,1970791,1976791,1981891,1982891,
1984891,1987891,1988891,1993991,1995991,1998991,3001003,3002003,3007003,
3016103,3026203,3064603,3065603,3072703,3073703,3075703,3083803,3089803,
3091903,3095903,3103013,3106013,3127213,3135313,3140413,3155513,3158513,
3160613,3166613,3181813,3187813,3193913,3196913,3198913,3211123,3212123,
3218123,3222223,3223223,3228223,3233323,3236323,3241423,3245423,3252523,
3256523,3258523,3260623,3267623,3272723,3283823,3285823,3286823,3288823,
3291923,3293923,3304033,3305033,3307033,3310133,3315133,3319133,3321233,
3329233,3331333,3337333,3343433,3353533,3362633,3364633,3365633,3368633,
3380833,3391933,3392933,3400043,3411143,3417143,3424243,3425243,3427243,
3439343,3441443,3443443,3444443,3447443,3449443,3452543,3460643,3466643,
3470743,3479743,3485843,3487843,3503053,3515153,3517153,3528253,3541453,
3553553,3558553,3563653,3569653,3586853,3589853,3590953,3591953,3594953,
3601063,3607063,3618163,3621263,3627263,3635363,3643463,3646463,3670763,
3673763,3680863,3689863,3698963,3708073,3709073,3716173,3717173,3721273,
3722273,3728273,3732373,3743473,3746473,3762673,3763673,3765673,3768673,
3769673,3773773,3774773,3781873,3784873,3792973,3793973,3799973,3804083,
3806083,3812183,3814183,3826283,3829283,3836383,3842483,3853583,3858583,
3863683,3864683,3867683,3869683,3871783,3878783,3893983,3899983,3913193,
3916193,3918193,3924293,3927293,3931393,3938393,3942493,3946493,3948493,
3964693,3970793,3983893,3991993,3994993,3997993,3998993,7014107,7035307,
7036307,7041407,7046407,7057507,7065607,7069607,7073707,7079707,7082807,
7084807,7087807,7093907,7096907,7100017,7114117,7115117,7118117,7129217,
7134317,7136317,7141417,7145417,7155517,7156517,7158517,7159517,7177717,
7190917,7194917,7215127,7226227,7246427,7249427,7250527,7256527,7257527,
7261627,7267627,7276727,7278727,7291927,7300037,7302037,7310137,7314137,
7324237,7327237,7347437,7352537,7354537,7362637,7365637,7381837,7388837,
7392937,7401047,7403047,7409047,7415147,7434347,7436347,7439347,7452547,
7461647,7466647,7472747,7475747,7485847,7486847,7489847,7493947,7507057,
7508057,7518157,7519157,7521257,7527257,7540457,7562657,7564657,7576757,
7586857,7592957,7594957,7600067,7611167,7619167,7622267,7630367,7632367,
7644467,7654567,7662667,7665667,7666667,7668667,7669667,7674767,7681867,
7690967,7693967,7696967,7715177,7718177,7722277,7729277,7733377,7742477,
7747477,7750577,7758577,7764677,7772777,7774777,7778777,7782877,7783877,
7791977,7794977,7807087,7819187,7820287,7821287,7831387,7832387,7838387,
7843487,7850587,7856587,7865687,7867687,7868687,7873787,7884887,7891987,
7897987,7913197,7916197,7930397,7933397,7935397,7938397,7941497,7943497,
7949497,7957597,7958597,7960697,7977797,7984897,7985897,7987897,7996997,
9002009,9015109,9024209,9037309,9042409,9043409,9045409,9046409,9049409,
9067609,9073709,9076709,9078709,9091909,9095909,9103019,9109019,9110119,
9127219,9128219,9136319,9149419,9169619,9173719,9174719,9179719,9185819,
9196919,9199919,9200029,9209029,9212129,9217129,9222229,9223229,9230329,
9231329,9255529,9269629,9271729,9277729,9280829,9286829,9289829,9318139,
9320239,9324239,9329239,9332339,9338339,9351539,9357539,9375739,9384839,
9397939,9400049,9414149,9419149,9433349,9439349,9440449,9446449,9451549,
9470749,9477749,9492949,9493949,9495949,9504059,9514159,9526259,9529259,
9547459,9556559,9558559,9561659,9577759,9583859,9585859,9586859,9601069,
9602069,9604069,9610169,9620269,9624269,9626269,9632369,9634369,9645469,
9650569,9657569,9670769,9686869,9700079,9709079,9711179,9714179,9724279,
9727279,9732379,9733379,9743479,9749479,9752579,9754579,9758579,9762679,
9770779,9776779,9779779,9781879,9782879,9787879,9788879,9795979,9801089,
9807089,9809089,9817189,9818189,9820289,9822289,9836389,9837389,9845489,
9852589,9871789,9888889,9889889,9896989,9902099,9907099,9908099,9916199,
9918199,9919199,9921299,9923299,9926299,9927299,9931399,9932399,9935399,
9938399,9957599,9965699,9978799,9980899,9981899,9989899,
781};
int main()
{
    scanf("%d %d",&a,&b);
    for(int i=1;i<=781;i++)
    if(db[i]>=a && db[i]<=b) printf("%d\n",db[i]);
    return 0;
}
/*const int N=100000001;
int P[N],a,b,ans,sum;
bool Isp[N];
void Euler(int x){>//欧拉筛法
    for(int i=2;i<=x;i++){
        if(Isp[i]) P[++P[0]]=i;
        for(int j=1;i*P[j]<=x && j<=P[0];j++){
            Isp[i*P[j]]=false;
            if(i%P[j]==0) break;
        }
    }
}
bool hw(int x)
{
    int x2=x,y=0;
    while (x2!=0)
    {
        y=y*10+x2%10;
        x2/=10;
    } 
    if (x==y) return true;
    else return false;
}
int main()
{
    memset(Isp,true,sizeof(Isp));Isp[1]=0;
    scanf("%d %d",&a,&b);
    Euler(b);
    for(int i=a;i<=b;i++)
        if(hw(i) && Isp[i]){
            printf("%d,",i);
            sum++;
            if(sum%9==0) printf("\n");
        }
    printf("\n%d",sum);
    return 0;
}*/

方法2(观察数据特征)

我用的不是制造回文数,是从a找到b。那怎么会不超时呢?

1、我从奇数开始找,每次+22、我发现,没有偶数位的回文质数!省了一大把的时间啊!

虽说还是很慢,不过很好写就是了!哈哈。

下面列核心的三个判断:

    bool ok(int k)   //回文数
    {     
        int a[10],i=0;     
        while (k>0){a[i]=k%10;k/=10;i++;}
        for(int j=0;j<i;j++)if(a[j]!=a[i-j-1])return false;   
        return true;     
    }
    bool ws(int k)  //位数
    {
        if(k>=10 && k<100 && k!=11 || k>=1000 && k<10000)return false;
        if(k>=100000 && k<1000000 || k>=10000000 && k<100000000)return false;
        return true;
    }
    bool ss(int k)   //素数
    {     
        for(int i=3;i*i<=k;i+=2)if(k%i==0)return false;     
        return true;
    }
更优的方法是制造回文数,这个我就不说了。给个赞吧!

P1720 月落乌啼算钱(斐波那契数列)

# 月落乌啼算钱(斐波那契数列)

## 题目背景

(本道题目木有隐藏歌曲……不用猜了……)

《爱与愁的故事第一弹·heartache》最终章。

吃完 pizza,月落乌啼知道超出自己的预算了。为了不在爱与愁大神面前献丑,只好还是硬着头皮去算钱……

## 题目描述

算完钱后,月落乌啼想着:“你 TMD 坑我,(以下用闽南语读)归粒靠杯靠亩诶,(以下用英读)是伊特游!”于是当爱与愁大神问多少钱时,月落乌啼说了一堆乱码。爱与愁大神说:“算了算了,我只问第 $n$ 样菜价格多少?”月落乌啼写出了:

$$F_n=\dfrac{(\frac{1+\sqrt{5}}{2})^n-(\frac{1-\sqrt{5}}{2})^n}{\sqrt{5}}$$

[](![](https://cdn.luogu.com.cn/upload/pic/507.png))

由于爱与愁大神学过编程,于是就用 $1$ 分钟的时间求出了 $F_n$ 的结果。月落乌啼为此大吃一惊。你能学学爱与愁大神求出 $F_n$ 的值吗?

## 输入格式

一行一个自然数 $n$。

## 输出格式

只有 $1$ 行一个实数 $F_n$,保留两位小数。

## 样例 #1

### 样例输入 #1

```
6
```

### 样例输出 #1

```
8.00
```

## 提示

对于所有数据:$0 \leq n\leq 48$。

警策看取 
更新时间:2019-10-22 19:04:32
在 Ta 的博客查看
这题是一个求斐波那契数列的题。

提供5种解法。

解法1
递归。

代码
#include <bits/stdc++.h>
using namespace std;
long long f(int n) {
    if(n == 1||n == 2)return 1;
    return f(n - 1) + f(n - 2);
}

int main() {
    int n;
    cin >> n;
    cout << f(n) <<".00"<< endl;
    return 0;
}
可是,超时。

在洛谷,似乎没有无限栈,还爆空间了。

那么,有什么办法可以解决这个问题呢?

于是,就有了解法2.

解法2
可以记录已经算过的值,避免重复计算,大大提升效率。

代码
#include <bits/stdc++.h>
using namespace std;
long long fa[100] = { 0, 1, 1 };//前几个写进去
long long f(int n) {
    if (!fa[n]) {//算过的直接返回,没算过的计算
        fa[n] = f(n - 1) + f(n - 2);
    }
    return fa[n];
}

int main() {
    int n;
    cin >> n;
    cout << f(n) <<".00"<< endl;
    return 0;
}
但是,WA,80.

为什么呢?

问题出在if (!fa[n])这边。当输入是0时,
�
(
0
)
=
0
f(0)=0,因此会又递归,所以WA了。

那么,应该加个特判,或用其他方法解决问题,代码这里不贴了,大家自己想想吧。

但是,有没有更好理解的办法呢?

解法3
递推。

代码
#include <bits/stdc++.h>
using namespace std;
int f[50] = { 0, 1, 1 };
int main() {
    int n;
    cin >> n;
    for (int i = 3; i <= n; ++i) {
        f[i] = f[i - 1] + f[i - 2];//按照斐波那契的公式算。
    }
    cout << f[n] << ".00";
    return 0;
}
额外提供两种解法。

解法4
三变量法。

#include<bits/stdc++.h>
using namespace std;

int main(){
	long long a,b,c=0,num=0;
	cin>>num;
	a=b=1;//初始值为1
	for(int i=3;i<=num;++i){
		c=b+a;//算第个数
		a=b;//b的值赋给a
		b=c;//c的值赋给b 
	} 
	cout<<c<<".00";
	return 0;
}

能理解的尽量理解吧。

解法5
公式法。

P5724 【深基4.习5】求极差 / 最大跨度值

# 【深基4.习5】求极差 / 最大跨度值

## 题目描述

给出 $n$ 和 $n$ 个整数 $a_i$,求这 $n$ 个整数中的极差是什么。极差的意思是一组数中的最大值减去最小值的差。

## 输入格式

第一行输入一个正整数 $n$,表示整数个数。

第二行输入 $n$ 个整数 $a_1,a_2 \dots a_n$,以空格隔开。

## 输出格式

输出一个整数,表示这 $n$ 个整数的极差。

## 样例 #1

### 样例输入 #1

```
6
1 1 4 5 1 4
```

### 样例输出 #1

```
4
```

## 提示

数据保证,$1 \leq n\leq 100$,$0\le a_i \le 1000$。
我的思路是将存在a数组里,然后sort一边,用a[n] 即最大- a[1] 即最小即可食用

#include<bits/stdc++.h>
using namespace std;
int a[100001];
int main()
{
	int n;
	cin>>n;
    for(int i=1;i<=n;i++)
    {
    	scanf("%d",&a[i]);
	}
	sort(a+1,a+n+1);
	cout<<a[n]-a[1];
    return 0;
}

P1075 [NOIP2012 普及组] 质因数分解

# [NOIP2012 普及组] 质因数分解

## 题目描述

已知正整数 $n$ 是两个不同的质数的乘积,试求出两者中较大的那个质数。

## 输入格式

输入一个正整数 $n$。

## 输出格式

输出一个正整数 $p$,即较大的那个质数。

## 样例 #1

### 样例输入 #1

```
21
```

### 样例输出 #1

```
7
```

## 提示

$1 \le n\le 2\times 10^9$

NOIP 2012 普及组 第一题
本题考数学。

首先要知道唯一分解定理:一个数能且只能分解为一组质数的乘积。可知,若输入的数满足题目条件,他就只能分解为两个质数的乘积。所以在比他小且大于1的自然数中,只有那两个数能整除它,之间不可能再有任何合数或质数能整除它了,因为最小的能整除它的合数已经是他本身了。

所以代码就很容易实现了

#include<cstdio>
int main()
{
    int n;
    scanf("%d",&n);
    for(int i=2;i<=n;++i)
            if(n%i==0)
            {
                    printf("%d",n/i);
                    return 0;
            }
}

P5725 【深基4.习8】求三角形

# 【深基4.习8】求三角形

## 题目描述

模仿例题,打印出不同方向的正方形,然后打印三角形矩阵。中间有个空行。

## 输入格式

输入矩阵的规模,不超过 $9$。

## 输出格式

输出矩形和正方形

## 样例 #1

### 样例输入 #1

```
4
```

### 样例输出 #1

```
01020304
05060708
09101112
13141516

      01
    0203
  040506
07080910
```

luosw 
更新时间:2020-03-17 09:10:08
在 Ta 的博客查看
愉快的模拟。

我们先来分析一下题意:

题意简述
模仿例题,打印出不同方向的正方形,然后打印三角形矩阵。中间有个空行。
只有这么多了,好,不说废话,开始分析。

题目分析
这道题我们可以采取这样的策略:

靠循环解决问题

我们需要两个大号的循环分别输出正方形和三角形。

正方形只要判断循环变量 
�
≡
1
(
m
o
d
�
)
i≡1(modn) 我们就换行,如果小于
10
10就在前面补
0
0。

三角形则需要建立一个变量 
�
�
�
cnt 来输出数字,用前面的空格数量 
�
i 来作为 while 循环的条件。

好,分析结束,上代码。

代码
#include<bits/stdc++.h>
using namespace std;
int n,i,cnt;
int main(){
	scanf("%d",&n);
	for(i=1;i<=n*n;i++){
		if(i%n==1&&i!=1){
			printf("\n");	//如果到了边缘就换行 
		}
		if(i<10){
			printf("0");	//如果小于10就输出0	
		}
		printf("%d",i);	//输出数字 
	}
	printf("\n\n");	//中间的空行和最后一行正方形的换行
	i=2*n;
	while(i>0){//按照剩余的空位判断 
		i-=2;
		for(int j=0;j<i;j++){
			printf(" ");
		}
		for(int j=0;j<(2*n-i)/2;j++){
			cnt++;
			if(cnt<10){
				printf("0");
			}
			printf("%d",cnt);
		}
		printf("\n");
	}
    return 0;
} 

P5726 【深基4.习9】打分

# 【深基4.习9】打分

## 题目描述

现在有 $n(n \le 1000)$ 位评委给选手打分,分值从 $0$ 到 $10$。需要去掉一个最高分,去掉一个最低分(如果有多个最高或者最低分,也只需要去掉一个),剩下的评分的平均数就是这位选手的得分。现在输入评委人数和他们的打分,请输出选手的最后得分,精确到 $2$ 位小数。

## 输入格式

第一行输入一个正整数 $n$,表示有 $n$ 个评委。

第二行输入 $n$ 个正整数,第 $i$ 个正整数表示第 $i$ 个评委打出的分值。

## 输出格式

输出一行一个两位小数,表示选手的最后得分。

## 样例 #1

### 样例输入 #1

```
5
9 5 6 8 9
```

### 样例输出 #1

```
7.67
```

## 提示

数据保证,$3 \leq n \leq 1000$,每个评委打出的分值为为 $0$ 到 $10$(含 $0$ 与 $10$)之间的整数。
#include<bits/stdc++.h>
using namespace std;
int n,a[10001];
double ans;
int main()
{
	cin>>n;
	for(int i=1;i<=n;i++) cin>>a[i];
	sort(a+1,a+n+1);
	for(int i=2;i<=n-1;i++) ans+=a[i];
	printf("%.2lf",ans/(n-2));
	return 0;
}

P1089 [NOIP2004 提高组] 津津的储蓄计划

# [NOIP2004 提高组] 津津的储蓄计划

## 题目描述

津津的零花钱一直都是自己管理。每个月的月初妈妈给津津 $300$ 元钱,津津会预算这个月的花销,并且总能做到实际花销和预算的相同。

为了让津津学习如何储蓄,妈妈提出,津津可以随时把整百的钱存在她那里,到了年末她会加上 $20\%$ 还给津津。因此津津制定了一个储蓄计划:每个月的月初,在得到妈妈给的零花钱后,如果她预计到这个月的月末手中还会有多于 $100$ 元或恰好 $100$ 元,她就会把整百的钱存在妈妈那里,剩余的钱留在自己手中。


例如 $11$月初津津手中还有 $83$ 元,妈妈给了津津 $300$ 元。津津预计$11$月的花销是 $180$ 元,那么她就会在妈妈那里存 $200$ 元,自己留下 $183$ 元。到了 $11$ 月月末,津津手中会剩下 $3$ 元钱。


津津发现这个储蓄计划的主要风险是,存在妈妈那里的钱在年末之前不能取出。有可能在某个月的月初,津津手中的钱加上这个月妈妈给的钱,不够这个月的原定预算。如果出现这种情况,津津将不得不在这个月省吃俭用,压缩预算。


现在请你根据 $2004$ 年 $1$ 月到 $12$ 月每个月津津的预算,判断会不会出现这种情况。如果不会,计算到 $2004$ 年年末,妈妈将津津平常存的钱加上 $20\%$ 还给津津之后,津津手中会有多少钱。

## 输入格式

$12$ 行数据,每行包含一个小于 $350$ 的非负整数,分别表示 $1$ 月到 $12$ 月津津的预算。

## 输出格式

一个整数。如果储蓄计划实施过程中出现某个月钱不够用的情况,输出 $-X$,$X$ 表示出现这种情况的第一个月;否则输出到 $2004$ 年年末津津手中会有多少钱。

注意,洛谷不需要进行文件输入输出,而是标准输入输出。

## 样例 #1

### 样例输入 #1

```
290
230
280
200
300
170
340
50 
90 
80 
200
60
```

### 样例输出 #1

```
-7
```

## 样例 #2

### 样例输入 #2

```
290 
230 
280 
200 
300 
170 
330 
50 
90 
80 
200 
60
```

### 样例输出 #2

```
1580
```

#include<iostream>
using namespace std;
int money,cost,mama,flag=1,monthofdeath;  //money代表在津津手里的钱,cost代表花费的钱,mama代表在妈妈手里的100元的张数,flag=1代表尚未透支,monthofdeath代表死亡月份 
int main ()
{
    for(int i=1;i<=12;i++)
    {
        money+=300;  //每个月津津手里的钱都会增加300 
        cin>>cost;     //输入这个月的花销 
        money-=cost;     // 津津手里的钱减去这个月的花销等于剩余的钱 
           if(money<0)     //若剩余的钱小于0, 
           {     
              flag=0;      //旗帜倒下,即已经透支 
              monthofdeath=i;    //输出死亡月份 
              break;            //终止循环 
           }
        mama+=money/100;    //剩余的钱整除100即为在妈妈手里的100元的张数 
        money%=100;         //用100去模剩余的钱即为月底幸存的钱         
    }    
    if(flag==1)      //若旗帜未倒下,即坚持到年底还没有透支 
    {
        money+=mama*120;    //剩余的钱 
        cout<<money;
    }            
    else
    {
        cout<<-monthofdeath;
    }    
    return 0;
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

时雨h

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值