一、前言
这篇题解是我本着和大家分享交流的目的写出来的,所以大家如果有自己独到的见解,欢迎一起交流,同时也希望能够帮助大家。
二、题解部分
1、A-上下金字塔_2024春算法训练2——循环结构 (nowcoder.com)
非常经典的一道循环,考察了嵌套循环结构。这类题目就是大循环里面有多个循环,不同的循环控制着不同的变量。首先我们可以将这道题目简化成打印一个普通的由符号组成的上金字塔。下图为我对于该类题目的做题步骤:
第一步:我们先按照步骤打印图中的a的三角形,第一步明确这个三角形是由行数,符号数,空格数三部分组成;
第二步:我们找他们之间的关系,可以发现符号个数随着行数变化而有规律的变化,空格数也是(假设行数为i,则符号数为2*i-1,空格数为(最大行数设为k)k-i)。
第三步:通过观察可以发现“自变量”就是行数,“因变量”就是符号数和空格数。那么我们怎么样用代码实现这个发现呢?下面是伪代码:
代码:
回到本题,要求是打印上下三角形,可以理解为打印一个上三角和一个下三角;
本题代码:
#include<iostream>
using namespace std;
int main()
{
int n;
while(cin>>n&&n)
{
/*上三角*/
for(int i=1;i<=n;i++)
{
for(int j=n-1;j>=i;j--)cout<<" ";
for(int j=1;j<=2*i-1;j++)cout<<"*";
cout<<endl;
}
/*下三角*/
for(int i=n+1;i<=2*n-1;i++)
{
for(int j=1;j<=i-n;j++)cout<<' ';
for(int j=2*(2*n-i)-1;j>=1;j--)cout<<"*";
cout<<endl;
}
}
return 0;
}
2.B-数字三角形_2024春算法训练2——循环结构 (nowcoder.com)
思路同第一题
/*规律是每一行数字的个数等于层数,数字循环一次加一*/
#include<iostream>
using namespace std;
int main()
{
int n;
cin>>n;
int cnt=1;
/*外层循环行数*/
for(int i=1;i<=n;i++)
{
/*内层循环输出数字的个数*/
for(int j=1;j<=i;j++)
printf("%4d",cnt++);
cout<<endl;
}
return 0;
}
3.C-字符金字塔_2024春算法训练2——循环结构 (nowcoder.com)
本题与第一题讲的样例唯一不同的是每一行字符的变换
#include<iostream>
using namespace std;
int main()
{
char ch;
cin>>ch;
int n=ch-'A'+1;
/*外层循环行数*/
for(int i=1;i<=n;i++)
{
/*空格数随着行数变化而变化*/
for(int j=n-i;j>=1;j--)cout<<" ";
char t='A';
/*每一行左边的字符*/
for(int j=1;j<=(2*i-1)/2;j++)
{
printf("%c",t);
t++;
}
/*中间的字符*/
printf("%c",t);
t--;
/*右边的字符*/
for(int j=i+1;j<=2*i-1;j++)
{
printf("%c",t);
t--;
}
cout<<endl;
}
return 0;
}
4、D-箭形图案_2024春算法训练2——循环结构 (nowcoder.com)
和样例一模一样
#include<iostream>
using namespace std;
int main()
{
int n;
while((scanf("%d",&n))!=EOF)
{
for(int i=1;i<=n+1;i++)
{
for(int j=(n+1-i)*2;j>=1;j--)cout<<" ";
for(int j=1;j<=i;j++)cout<<"*";
cout<<endl;
}
for(int i=n+2;i<=2*n+1;i++)
{
for(int j=(n+1-(2*(n+1)-i))*2;j>=1;j--)cout<<" ";
for(int j=2*(n+1)-i;j>=1;j--)cout<<"*";
cout<<endl;
}
}
return 0;
}
5.E-牛牛学数列2_2024春算法训练2——循环结构 (nowcoder.com)
本题考察简单循环,注意变量类型为浮点数
#include<iostream>
using namespace std;
int main()
{
double sum=0;
int n;
cin>>n;
for(int i=1;i<=n;i++)
{
sum+=1.0/i;
}
printf("%.6f",sum);
return 0;
}
6、F-牛牛学数列6_2024春算法训练2——循环结构 (nowcoder.com)
本题考察用循环实现简单递归,递归公式如下:
代码:
#include<iostream>
using namespace std;
int dp[24];
int main()
{
int n;
cin>>n;
dp[1]=0,dp[2]=1,dp[3]=1;
for(int i=4;i<=20;i++)dp[i]=dp[i-3]+2*dp[i-2]+dp[i-1];
cout<<dp[n];
return 0;
}
7、G-多组数据a+b III_2024春算法训练2——循环结构 (nowcoder.com)
考察多组数据的输入,代码如下:
#include<iostream>
using namespace std;
int main()
{
int a,b;
while(cin>>a>>b&&a&&b)
{
cout<<a+b<<endl;
}
return 0;
}
8、H-[NOIP2018]标题统计_2024春算法训练2——循环结构 (nowcoder.com)
你是否还记得有一个读入函数叫做getchar();代码如下:
#include<iostream>
using namespace std;
int main()
{
char ch;
int res=0;
while((ch=getchar())!=EOF)
{
if(ch!=' '&&ch!='\n')res++;
}
cout<<res<<endl;
return 0;
}
9、I-有趣的二进制_2024春算法训练2——循环结构 (nowcoder.com)
第一个做法:首先明确原码,反码,补码的概念然后用三个数组手动模拟,一个是原码,一个是反码,另外一个是补码;进位挺麻烦的;
第二个做法:巧用unsigned long long ,通过下面的程序我们不难发现,如果一个数是负数的话unsigned long long 恰好是将其以补码的形式储存起来的。然后用位运算统计1的个数即可。
#include<iostream>
using namespace std;
int main()
{
unsigned long long x;
while(cin>>x)
{
int cnt=0,ans=0;
while(x)
{
if(x&1)cnt++;
x>>=1;
}
cout<<cnt<<endl;
}
return 0;
}
10、J-[NOIP2006]数列_2024春算法训练2——循环结构 (nowcoder.com)
一道找规律的题,,,
1二进制对应01(1=3^0*1) 2二进制对应10 (3=3^1*1+3^0*0) 3二进制对应11(4=3^1*1+3^0*1) 4二进制对应100(9=3^2*1+3^1*0+3^0*0).........
从二进制的角度来看如果该数二进制末位上为1就加上该位的单位值,代码如下
#include<iostream>
using namespace std;
typedef unsigned long long ll;
int main()
{
int x,n;
cin>>x>>n;
ll t=1,ans=0;
while(n)
{
if(n&1)ans+=t;
n>>=1;
t*=x;
}
cout<<ans;
return 0;
}
11.K-[NOIP2015]金币_2024春算法训练2——循环结构 (nowcoder.com)
本题考察循环条件的控制,即天数大于k后循环就不能再进行,代码如下:
#include<iostream>
using namespace std;
int main()
{
int cnt=0,ans=0;
int k;
cin>>k;
for(int i=1;i<=10000&&cnt<k;i++)
{
for(int j=1;j<=i&&cnt<k;j++)
ans+=i,cnt++;
}
cout<<ans<<endl;
return 0;
}
12、L-[NOIP2000]进制转换_2024春算法训练2——循环结构 (nowcoder.com)
这题主要是将数转换成负进制:设R为非零正整数,推导如下:
通过推导我们可以发现如果按照常规的方式求一个数的进制数,那么我们在余数(-k)为负时,我们可以从上一位借数来表示。余数(-k)加上R(即减去-R)变为正数,而且很明显这个正数小于R,同时上一为一位要减去R(也就是借给下一位,即加上-R);
代码如下:
#include<iostream>
#include<algorithm>
using namespace std;
typedef long long ll;
int oti(int a){
if(a>=10)return char('A'+a-10);
else return char(a+'0');
}
int main(){
ll n,p2;
cin>>n>>p2;
ll s=n;
string ras="";
if(n==0){
printf("0=0(base%d)",p2);
return 0;
}
while(s!=0){
int m=s%p2;
if(m<0)m-=p2,s+=p2;
ras+=oti(m);
s/=p2;
}
reverse(ras.begin(),ras.end());
cout<<n<<"=";
cout<<ras;
printf("(base%d)",p2);
return 0;
}
13、M-[NOIP1999]Cantor表_2024春算法训练2——循环结构 (nowcoder.com)
发现的规律:
代码如下:
#include<iostream>
using namespace std;
int main()
{
/*先枚举第几项*/
int n;
cin>>n;
int k=1;
for(k=1;(k+1)*k/2<=n;k++);
k--;
n-=(k+1)*k/2;
/*顺序无所谓*/
if(k%2==0)
{
if(n==0)cout<<k<<"/"<<1;
else cout<<(k-n+2)<<"/"<<n;
}
else
{
if(!n)cout<<1<<"/"<<k;
else cout<<n<<"/"<<(k+2-n);
}
return 0;
}
14、N-[NOIP2005]陶陶摘苹果_2024春算法训练2——循环结构 (nowcoder.com)
这题就是拿淘淘能够到的最大距离去和十个数比大小
#include<iostream>
using namespace std;
int apple[10];
int main()
{
int res=0;
for(int i=1;i<=10;i++)
{
cin>>apple[i];
}
int h;
cin>>h;
for(int i=1;i<=10;i++)if(h+30>=apple[i])res++;
cout<<res<<endl;
return 0;
}
15、O-[NOIP2004]津津的储蓄计划_2024春算法训练2——循环结构 (nowcoder.com)
while循环模拟12个月
{
手上多300块钱
用手上的钱减去剩余的钱
如果手上的钱为负数,终止循环
否则循环继续
手上整百的钱交给妈妈存起来
}
如果没有预算超出的现象则最终的钱数为存的加上手上的
#include<iostream>
using namespace std;
int main()
{
int t=12;
int h=0,c=0;
bool flag=true;
/*用flag判断是否出现预算超出的情况发生*/
while(t--)
{
int x;
cin>>x;
h+=300;
h-=x;
if(h<0)
{
flag=false;
cout<<-1*(12-t);
break;
}
c+=h/100;
h%=100;
}
if(flag)cout<<(int)c*(120)+h;
return 0;
}
16、P-[NOIP2002]级数求和_2024春算法训练2——循环结构 (nowcoder.com)
这个用for循环枚举就可以了,代码如下:
#include<iostream>
#include<cmath>
using namespace std;
double eps=1e-2;
int main()
{
double n;
cin>>n;
int t=1;
double sum=0;
for(int i=1;i<=100000000&&sum<=n;i++)
{
t=i;
sum+=1.0/i;
}
cout<<t<<endl;
return 0;
}
17、Q-[NOIP2009]多项式输出_2024春算法训练2——循环结构 (nowcoder.com)
属于是比较典型的模拟题了,按照题目要求去模拟即可,代码如下:
#include<iostream>
using namespace std;
int main()
{
int n,cnt=0;
cin>>n;
for(int i=1;i<=n+1;i++)
{
int x;
cin>>x;
/*0全部忽略,只有0的个数等于项数时才有特殊情况,这种情况判断cnt即可*/
if(x)
{
/*最外面的分支结构讨论不同的项,这题比较特殊的项有首项,一次方项,以及末项*/
/*首项*/
if(i==1)
{
if(x==1)cout<<"x^"<<n+1-i;
else if(x==-1)cout<<"-x^"<<n+1-i;
else cout<<x<<"x^"<<n+1-i;
}
/*中间项*/
else if(i<n+1)
{
bool flag=0;
if(x<0)flag=true,x*=-1;
if(flag)cout<<"-";
else cout<<"+";
if(i!=n)
{
if(x==1)cout<<"x^"<<n+1-i;
else if(x==-1)cout<<"x^"<<n+1-i;
else cout<<x<<"x^"<<n+1-i;
}
else
{
if(x==1)cout<<"x";
else if(x==-1)cout<<"x";
else cout<<x<<"x";
}
}
/*末项*/
else if(i==n+1)
{
bool flag=0;
if(x<0)flag=true,x*=-1;
if(flag)cout<<"-";
else cout<<"+";
cout<<x;
}
}else cnt++;
}
/*如果所有项的系数全部为0,则输出一个0*/
if(cnt==n+1)cout<<0;
return 0;
}
18、R-数字计数_2024春算法训练2——循环结构 (nowcoder.com)
注意不能算重复的数字,数据范围比较小用一个数组记录一个数字出现的次数,再用一个数组存数然后排序即可。
代码:
#include<iostream>
#include<algorithm>
using namespace std;
int a[100010],ha[1000000];
bool cmp(int a,int b)
{
return a<b;
}
int main()
{
int n,cnt=0;
cin>>n;
for(int i=1;i<=n;i++)
{
int x;
cin>>x;
if(!ha[x])a[++cnt]=x;
ha[x]++;
}
sort(a+1,a+1+cnt,cmp);
cout<<a[cnt]-a[cnt-1]<<" "<<a[cnt]-a[2]<<" "<<a[cnt-1]-a[2]<<" "<<a[cnt-1]-a[1];
return 0;
}
19、S-D博弈与核心能源动力_2024春算法训练2——循环结构 (nowcoder.com)
本题考察用while循环模拟,根据题意可知最后一定会到一种状态:钱不够,酒瓶不够,盖子不够;那么只要这三个条件不同时成立,那么就一定可以继续换酒;同时注意钱只有不为负数时才可以用来计算(题目条件有给出)。
代码如下:
#include<iostream>
using namespace std;
int main()
{
int money,k,g,p;
cin>>money>>k>>g>>p;
int ans=0,t=0;
while(k>=2||g>=4||money>=p)
{
/*用钱换*/
if(money>0)
{
t=money/p;
g+=t;
k+=t;
ans+=t;
money%=p;
}
/*用酒瓶换*/
t=k/2;
k%=2;
k+=t;
g+=t;
ans+=t;
/*用瓶盖换*/
t=g/4;
g%=4;
k+=t;
g+=t;
ans+=t;
}
cout<<ans<<endl;
return 0;
}
20、T-cayun日常之赏月_2024春算法训练2——循环结构 (nowcoder.com)
观察得出规律除了14,15以及1,0这两组之外,其他组的变化趋势不变;代码如下:
#include<iostream>
using namespace std;
int main()
{
int _;
cin>>_;
while(_--)
{
int a,b;
cin>>a>>b;
if(a==14&&b==15)cout<<14<<endl;
else if(a==1&&b==0)cout<<1<<endl;
else if(a<b)cout<<b+1<<endl;
else if(a>b)cout<<b-1<<endl;
}
return 0;
}