13415 - 津津的储蓄计划
时间限制 : 1 秒
内存限制 : 128 MB
津津的零花钱一直都是自己管理。每个月的月初妈妈给津津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年年末津津手中会有多少钱。
样例
输入
290 230 280 200 300 170 340 50 90 80 200 60
输出
-7
输入
290 230 280 200 300 170 330 50 90 80 200 60
输出
1580
#include<iostream>
using namespace std;
int main() {
int a[13],i=0;
int rest = 0,mom=0;
for (i = 1; i <= 12; i++) {
cin >> a[i];
}
for (i = 1; i <= 12; i++) {
rest += 300;
if (rest < a[i]) {
cout << (-1) * i << endl;
break;
}
else {
rest -= a[i];
if (rest >= 100) {
mom += (rest / 100)*100;
rest -= (rest / 100)*100;
}
}
}
//思考为什么要这个判断?
//因为如果没有这个判断,当出现钱不够用的情况下也会执行
if (i == 13) {
cout << mom * 120 / 100 + rest << endl;
}
return 0;
}
分析:很多人看到这题目觉得太复杂了,直接放弃。其实文字多不代表题目难,应该静下心来仔细慢慢读题,读懂题目意思。文字多的题一般逻辑思维都不会太难。
是否通过:
13422 - 开关灯(重点题)
时间限制 : 1 秒
内存限制 : 128 MB
假设有N盏灯(N为不大于5000的正整数),从1到N按顺序依次编号,初始时全部处于开启状态;有M个人(M为不大于N的正整数)也从1到M依次编号。
第一个人(1号)将灯全部关闭,第二个人(2号)将编号为2的倍数的灯打开,第三个人(3号)将编号为3的倍数的灯做相反处理(即,将打开的灯关闭,将关闭的灯打开)。依照编号递增顺序,以后的人都和3号一样,将凡是自己编号倍数的灯做相反处理。
请问:当第M个人操作之后,哪几盏灯是关闭的,按从小到大输出其编号,其间用逗号间隔。
输入
输入正整数N和M,以单个空格隔开。
输出
顺次输出关闭的灯的编号,其间用逗号间隔。
样例
输入
10 10
输出
1,4,9
答案:
#include<iostream>
using namespace std;
typedef struct light {
int number;//灯的编号
bool flag;//灯的状态,true表示开着,false表示关闭
}light;
int main() {
int N, M;//n,m分别表示灯的个数和人的个数
cin >> N >> M;
light a[5001];//定义灯的一个数组
int b[5001];//定义人的数组
//初始化
for (int i = 1; i <= N; i++) {
a[i].number = i;
a[i].flag = true;
}
for (int i = 1; i <= M; i++) {
b[i] = i;
}
//关灯
for (int i = 1; i <= M; i++) {
for (int j = 1; j <= N; j++) {
if (j % i == 0) {
if (i == 1) {//第一个人关掉全部灯
a[j].flag = false;
}
else if (i == 2) {//第二个人将编号为2的倍数的灯打开
a[j].flag = true;
}
else if (i >= 3) {//其他人将编号为i的倍数的灯做相反操作
//即如果是开着的则关闭,如果是关闭的则打开它
if (a[j].flag == true) {
a[j].flag = false;
}
else {
a[j].flag = true;
}
}
}
}
}
//统计关闭的灯的数量
int count = 0;
for (int i = 1; i <= N; i++) {
if (a[i].flag == false) {
count++;
}
}
//打印关闭灯的编号
for (int i = 1; i <= N; i++) {
if (a[i].flag == false&&count!=1) {
cout << a[i].number << ',';
count--;
}
else if (a[i].flag == false && count == 1) {
cout << a[i].number;
}
}
return 0;
}
分析:这道题难度还是有的。也有很多改编的版本。但是万变不离其宗。可能难的是不少人没有想到用结构体。还有就是第一个人和第二个人对灯的处理和后面的处理是不一样的。最后就是打印,由于不知道事先有多少个灯是关着的,如果直接打印,最后一个灯的编号后面是有逗号‘,’的。因此得事先统计关闭灯的数量。
是否通过:
13423 - 雇佣兵
时间限制 : 1 秒
内存限制 : 128 MB
雇佣兵的体力最大值为M,初始体力值为0、战斗力为N、拥有X个能量元素。
当雇佣兵的体力值恰好为M时,才可以参加一个为期M天的战斗期,战斗期结束体力值将为0。在同一个战斗期内,雇佣兵每连续战斗n天,战斗力就会上升1点,n为当前战斗期开始时的战斗力。
一个战斗期结束后,雇佣兵需要用若干个能量元素使其体力恢复到最大值M,从而参加下一个战斗期。每个能量元素恢复的体力值不超过当前的战斗力。每个能量元素只能使用一次。
请问:雇佣兵的战斗力最大可以到达多少。
输入
一行包括三个整数M、N、X,相邻两个整数之间用单个空格隔开。M、N、X均为不超过10000的正整数。
输出
输出一个整数,为雇佣兵的最大战斗力。
样例
输入
5 2 10
输出
6
答案:
#include<iostream>
using namespace std;
int main() {
int M, N, X;
int bodyPower = 0,used=0;
cin >> M >> N >> X;
while (X > 0) {
if (M % N == 0) {
used = M / N;
}
else {
used = M / N + 1;
}
if (used > X)break;
X -= used;
N += M / N;
}
cout << N << endl;
return 0;
}
分析:这个题我感觉我是没有把题目的意思理解透彻。希望看到的朋友给个你的理解。借鉴别人的思路编写通过。
是否通过:
13430 - 金币
时间限制 : 1 秒
内存限制 : 128 MB
国王将金币作为工资,发放给忠诚的骑士。第一天,骑士收到一枚金币;之后两天(第二天和第三天)里,每天收到两枚金币;之后三天(第四、五、六天)里,每天收到三枚金币;之后四天(第七、八、九、十天)里,每天收到四枚金币……这种工资发放模式会一直这样延续下去:当连续N天每天收到N枚金币后,骑士会在之后的连续N+1天里,每天收到N+1枚金币(N为任意正整数)。
你需要编写一个程序,确定从第一天开始的给定天数内,骑士一共获得了多少金币。
输入
一个整数(范围1到10000),表示天数。
输出
骑士获得的金币数。
样例
输入
6
输出
14
答案:
#include<iostream>
using namespace std;
int main() {
int day,sum=0,count=1,i=1,j=1;
cin >> day;
for (j = 1; j <= day;) {
i = 1;
while (i <= count) {
sum += count;
j++;
if (j > day) {
break;
}
i++;
}
count++;
}
cout << sum << endl;
return 0;
}
分析:这个题题目意思很简单,但是想一下子写出来还不是那么的容易,得用一个变量count记录在后续连续的count天每天发放金币的数量。当然这个题还有简便方法。可以用乘法运算简化。
是否通过:
13437 - 最长连号
时间限制 : 1 秒
内存限制 : 128 MB
输入 n 个正整数,要求输出最长的连号的长度。
连号指从小到大连续自然数。
输入
第一行,一个整数n。
第二行,n个整数 a_iai,之间用空格隔开。,之间用空格隔开。
输出
一个数,最长连号的个数。
样例
输入
10 3 5 6 2 3 4 5 6 8 9
输出
5
答案:
#include<iostream>
using namespace std;
int main() {
int n, count = 0;
int a[2000], max = 0;
cin >> n;
for (int i = 1; i <= n; i++) {
cin >> a[i];
}
if (n == 1) {
cout << n - 1 << endl;
}
else {
for (int i = 1; i < n; i++) {
if (a[i + 1] - a[i] == 1) {
count++;
}
else {
count = 0;
}
max = max < count ? count : max;
}
if (max == 0) {
cout << max << endl;
}
else {
cout << max+1 << endl;
}
}
return 0;
}
分析:这个题目看似简单,但是第一次上手,还是遇到不少问题。通过答案的测试用例。首先对这个题得有一个理解:
如果n等于1,则长度为0,不是为1.这是这个题最容易错的地方,我个人的理解是因为题目求的是连续的连号,故只有一个数是算不上连续,故为0。
如果n为2,如果输入2,3。此时长度为2。注意理解题目含义
是否通过: