c++题目_爆肝3题

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

题目描述

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

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

例如 1111月初津津手中还有 8383 元,妈妈给了津津 300300 元。津津预计1111月的花销是 180180 元,那么她就会在妈妈那里存 200200 元,自己留下 183183 元。到了 1111 月月末,津津手中会剩下 33 元钱。

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

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

输入格式

1212 行数据,每行包含一个小于 350350 的非负整数,分别表示 11 月到 1212 月津津的预算。

输出格式

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

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

输入输出样例

输入 #1复制

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

输出 #1复制

-7 

输入 #2复制

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

主要思路是对12个月份的支出进行统计,并计算出一个年度的总支出。在每个月份,你从标准的300个小时开始,然后减去这个月的支出。如果这个月的支出导致剩余的小时数为负数,程序会输出负数的月份,并结束程序。最后,程序会输出年度的总支出,考虑到1.2的兑换率。

#include <iostream>
using namespace std;

const int m = 300;

int main() {
    int h = 0, s = 0;       // 定义变量h和s,分别表示小时和总金额
    int a;                  // 定义变量a,用于存储输入的金额
    for (int i = 1; i < 13; i++) {
        cin >> a;           // 输入金额
        h += m;             // 每次循环累加300小时到h
        if (h < a) {
            cout << -i;     // 如果h小于a,则输出负的i,并结束程序
            return 0;
        }
        int left = h - a;   // 计算剩余的金额
        h = left % 100;     // 将剩余的金额转换为小时
        s += left - h;      // 累加剩余的金额到s
    }
    cout << s * 1.2 + h;    // 输出总金额,使用1.2作为兑换率
    return 0;
}

P1093 [NOIP2007 普及组] 奖学金

题目背景

NOIP2007 普及组 T1

题目描述

某小学最近得到了一笔赞助,打算拿出其中一部分为学习成绩优秀的前 55 名学生发奖学金。期末,每个学生都有 33 门课的成绩:语文、数学、英语。先按总分从高到低排序,如果两个同学总分相同,再按语文成绩从高到低排序,如果两个同学总分和语文成绩都相同,那么规定学号小的同学排在前面,这样,每个学生的排序是唯一确定的。

任务:先根据输入的 33 门课的成绩计算总分,然后按上述规则排序,最后按排名顺序输出前五名名学生的学号和总分。

注意,在前 55 名同学中,每个人的奖学金都不相同,因此,你必须严格按上述规则排序。例如,在某个正确答案中,如果前两行的输出数据(每行输出两个数:学号、总分) 是:

7 279  
5 279

这两行数据的含义是:总分最高的两个同学的学号依次是 77 号、55 号。这两名同学的总分都是 279279 (总分等于输入的语文、数学、英语三科成绩之和) ,但学号为 77 的学生语文成绩更高一些。

如果你的前两名的输出数据是:

5 279  
7 279

则按输出错误处理,不能得分。

输入格式

共 𝑛+1n+1 行。

第 11 行为一个正整数 𝑛≤300n≤300,表示该校参加评选的学生人数。

第 22 到 𝑛+1n+1 行,每行有 33 个用空格隔开的数字,每个数字都在 00 到 100100 之间。第 𝑗j 行的 33 个数字依次表示学号为 𝑗−1j−1 的学生的语文、数学、英语的成绩。每个学生的学号按照输入顺序编号为 1∼𝑛1∼n(恰好是输入数据的行号减 11)。

保证所给的数据都是正确的,不必检验。

输出格式

共 55 行,每行是两个用空格隔开的正整数,依次表示前 55 名学生的学号和总分。

输入输出样例

输入 #1复制

6
90 67 80
87 66 91
78 89 91
88 99 77
67 89 64
78 89 98

输出 #1复制

6 265
4 264
3 258
2 244
1 237

输入 #2复制

8
80 89 89
88 98 78
90 67 80
87 66 91
78 89 91
88 99 77
67 89 64
78 89 98

输出 #2复制

8 265
2 264
6 264
1 258
5 258

根据输入的学生成绩,先计算总分,然后按照规则进行排序,最后输出前五名学生的学号和总分。

在这段代码中,你首先读取一个整数n,表示学生的人数。接下来的n行中,每行包含三个用空格隔开的数字,表示学生的语文、数学和英语成绩。

然后,程序根据总分和规则进行排序。排序规则是先按照总分从高到低排序,如果两个学生的总分相同,再按照语文成绩从高到低排序,如果总分和语文成绩也相同,那么学号小的学生排在前面。

最后,程序输出前五名学生的学号和总分。

#include<bits/stdc++.h>
using namespace std;
struct stu{//学生信息
	int Id;
	int yw;
	int sx;
	int yy;
	int sum;
};stu a[301];
bool cmp(stu a,stu b){
	if(a.sum>b.sum)return true;
	else if(a.sum==b.sum && a.yw>b.yw)
		return true;
	else if(a.sum==b.sum && a.yw==b.yw && a.Id<b.Id) 
		return true;
	else
		return false;
}
int main(){
	int n,i;
	scanf("%d",&n);
	for(i=1;i<=n;i++){
		scanf("%d%d%d",&a[i].yw,&a[i].sx,&a[i].yy);
		a[i].sum=a[i].yw+a[i].sx+a[i].yy;
		a[i].Id=i;
	}
	sort(a+1,a+n+1,cmp);
	for(i=1;i<=5;i++)printf("%d %d\n",a[i].Id,a[i].sum);
	return 0;
}

P1068 [NOIP2009 普及组] 分数线划定

题目描述

世博会志愿者的选拔工作正在 A 市如火如荼的进行。为了选拔最合适的人才,A 市对所有报名的选手进行了笔试,笔试分数达到面试分数线的选手方可进入面试。面试分数线根据计划录取人数的 150%150% 划定,即如果计划录取 𝑚m 名志愿者,则面试分数线为排名第 𝑚×150%m×150%(向下取整)名的选手的分数,而最终进入面试的选手为笔试成绩不低于面试分数线的所有选手。

现在就请你编写程序划定面试分数线,并输出所有进入面试的选手的报名号和笔试成绩。

输入格式

第一行,两个整数 𝑛,𝑚(5≤𝑛≤5000,3≤𝑚≤𝑛)n,m(5≤n≤5000,3≤m≤n),中间用一个空格隔开,其中 𝑛n 表示报名参加笔试的选手总数,𝑚m 表示计划录取的志愿者人数。输入数据保证 𝑚×150%m×150% 向下取整后小于等于 𝑛n。

第二行到第 𝑛+1n+1 行,每行包括两个整数,中间用一个空格隔开,分别是选手的报名号 𝑘(1000≤𝑘≤9999)k(1000≤k≤9999)和该选手的笔试成绩 𝑠(1≤𝑠≤100)s(1≤s≤100)。数据保证选手的报名号各不相同。

输出格式

第一行,有 22 个整数,用一个空格隔开,第一个整数表示面试分数线;第二个整数为进入面试的选手的实际人数。

从第二行开始,每行包含 22 个整数,中间用一个空格隔开,分别表示进入面试的选手的报名号和笔试成绩,按照笔试成绩从高到低输出,如果成绩相同,则按报名号由小到大的顺序输出。

输入输出样例

输入 #1复制

6 3 
1000 90 
3239 88 
2390 95 
7231 84 
1005 95 
1001 88

输出 #1复制

88 5 
1005 95 
2390 95 
1000 90 
1001 88 
3239 88 

说明/提示

【样例说明】

𝑚×150%=3×150%=4.5m×150%=3×150%=4.5,向下取整后为 44。保证 44 个人进入面试的分数线为 8888,但因为 8888 有重分,所以所有成绩大于等于 8888 的选手都可以进入面试,故最终有 55 个人进入面试。

NOIP 2009 普及组 第二题

代码首先定义了一个结构体node,包含了学号和笔试成绩两个成员变量。然后定义了一个cmp函数用来进行排序,按照笔试成绩从高到低排序,如果成绩相同,则按照学号从小到大排序。

在主函数main中,首先读取了输入的选手总数n和计划录取的志愿者人数f。然后通过循环将每个选手的学号和笔试成绩存入结构体数组q中。接着对数组进行排序,排序规则按照cmp函数进行。然后计算出面试分数线的位置i,并统计笔试成绩大于等于面试分数线的选手数目js。最后输出面试分数线和进入面试的选手的人数,以及他们的学号和笔试成绩。

这段代码的实现逻辑基本符合题目要求,但是在对选手进行笔试成绩大于等于面试分数线的筛选时,使用了一个固定的位置j=i,这样会导致一些情况下统计错误。正确的做法应该是遍历数组q来统计笔试成绩大于等于面试分数线的选手数目。

#include<bits/stdc++.h>
using namespace std;
struct node{
    int num,s;
}q[1000000];
bool cmp(node a,node b){
    if(a.s==b.s)return a.num<b.num;
    return a.s>b.s;
}

int main(){
    int n,j,js=0;
    float f;
    cin>>n>>f;
    for(int i=1;i<=n;i++)
      cin>>q[i].num>>q[i].s;
    sort(q+1,q+1+n,cmp);
    int i=int(f*1.5);
    j=i;js=0;
    for(int k=1;k<=n;k++)
      if(q[k].s>=q[i].s)js++;
    cout<<q[i].s<<" "<<js<<endl;
    for(i=1;i<=n;i++){
        if(q[i].s>=q[j].s)
            cout<<q[i].num<<" "<<q[i].s<<endl;
    }
    return 0;
}

  • 16
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值