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:73个 7,17,...,727


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


百位7:29个 700~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

/

=

=

1

1

Sn=1+1/2+1/3+...+1/n=∑

k=1

n

 

k

1

明显地,

Sn为第

n个调和数。

欧拉推导过求调和级数有限多项和的表达式为

=

1

1

=

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、我从奇数开始找,每次+2;


2、我发现,没有偶数位的回文质数!省了一大把的时间啊!


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


下面列核心的三个判断:


   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;

}


目录
相关文章
|
2月前
|
编译器 C++
C++入门12——详解多态1
C++入门12——详解多态1
47 2
C++入门12——详解多态1
|
2月前
|
编译器 C语言 C++
C++入门3——类与对象2-2(类的6个默认成员函数)
C++入门3——类与对象2-2(类的6个默认成员函数)
38 3
|
2月前
|
存储 编译器 C语言
C++入门2——类与对象1(类的定义和this指针)
C++入门2——类与对象1(类的定义和this指针)
44 2
|
2月前
|
C++
C++入门13——详解多态2
C++入门13——详解多态2
87 1
|
2月前
|
程序员 C语言 C++
C++入门5——C/C++动态内存管理(new与delete)
C++入门5——C/C++动态内存管理(new与delete)
83 1
|
2月前
|
编译器 C语言 C++
C++入门4——类与对象3-1(构造函数的类型转换和友元详解)
C++入门4——类与对象3-1(构造函数的类型转换和友元详解)
29 1
|
2月前
|
存储 编译器 C++
C++入门3——类与对象2-1(类的6个默认成员函数)
C++入门3——类与对象2-1(类的6个默认成员函数)
49 1
|
2月前
|
编译器 C语言 C++
C++入门6——模板(泛型编程、函数模板、类模板)
C++入门6——模板(泛型编程、函数模板、类模板)
60 0
C++入门6——模板(泛型编程、函数模板、类模板)
|
2月前
|
存储 安全 编译器
【C++打怪之路Lv1】-- 入门二级
【C++打怪之路Lv1】-- 入门二级
28 0
|
2月前
|
自然语言处理 编译器 C语言
【C++打怪之路Lv1】-- C++开篇(入门)
【C++打怪之路Lv1】-- C++开篇(入门)
37 0