P2669 [NOIP 2015 普及组] 金币

记录9

#include <bits/stdc++.h>
using namespace std;
int main() {
	int n,cnt=0,ans=0;
	cin>>n;
	for(int i=1;;i++){
		for(int j=1;j<=i;j++){
			ans+=i;
			cnt++;
			if(cnt==n) break;
		}
		if(cnt==n) break;
	}
	cout<<ans;
    return 0;
}

突破点

n 天每天收到 n 枚金币

简单分析后,发现得到的金币数就是个数字三角形,顺序(由左到右,由上到下)

发现这个三角形后,还能继续优化上述代码,优化后的代码放在文章的补充部分

三角形长这样👇

1

2 2

3 3 3

4 4 4 4

5 5 5 5 5

n..............

n+1.............

思路

  1. 输入的天数就是数字三角形的截止的位置,然后全加起来
  2. 这个三角形就是一个简单的双重for循环
  3. 设置个计数器来找到数字,然后结束循环

代码简析

cnt是进行天数的计数,直到等于输入的天数n,才完成任务

ans是对金币的总数量进行累加,最后输出总数量

for(int i=1;;i++){...}

外层for循环for(int i=1;;i++),对应三角形的每一行,因为不知道具体在哪一行,所以中间的结束条件为空,即死循环,需要跳出循环(这也就是cnt存在的意义)

for(int j=1;j<=i;j++){
			ans+=i;
			cnt++;
			if(cnt==n) break;//跳出内层循环
		}
		if(cnt==n) break;//跳出外层循环

根据数字三角形将每一列的金钱数加起来,每加完后一个就用cnt++来计数,表示又计数一天

if(cnt==n) break;代表找到结束的天数了,即所有金币数累加完成,所有任务完成

出现两次的原因,因为第一次是跳出内层for循环(三角形的列),第二次跳出外层for循环(三角形的行)

补充

1

2 2

3 3 3

4 4 4 4

5 5 5 5 5

n..............

n+1.............

注意观察这个三角形,假设天数是9,那么前三行可以直接算,即1*1+2*2+3*3(六天的钱,三角形前3行)

剩下的三天(三角形第四行)再额外加上就行了

优化后代码(一层for循环实现)

#include <bits/stdc++.h>
using namespace std;
int main() {
	int day;
	int ans=0,cnt=1;
	cin>>day;
	for(int i=1;i<=day;i++){ 
		day=day-i;
		ans+=cnt*cnt;
		cnt++;
	}
	cout<<ans+day*cnt;
	return 0; 
}

ans用来存储三角形的层数之和(除了最后一层不满足外),即n层三角形n-1层的金币总数

cnt用来记录金币每次的增加1的情况(即三角形换行)

day=day-i;减去三角形每层的函数,即每天收到 n 枚金币的n 天

cout<<ans+day*cnt;

ans(前n-1层的三角形元素和,即n层三角形n-1层的金币总数)

day*cnt(最后一层没满,加上没满的最后一层)

注意:day=0的时候,代表三角形全满的情况,此时ans就存储了全部的三角形元素

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值