基础训练练习(no.5)

数字游戏

时间限制:C/C++ 1000MS,其他语言 2000MS
内存限制:C/C++ 64MB,其他语言 128MB
难度:简单+
分数:100 OI排行榜得分:14(0.1*分数+2*难度)

描述

        小 K 同学向小 P 同学发送了一个长度为 8 的 01 字符串 来玩数字游戏,小 P 同学想要知道字符串中究竟有多少个 1。
注意:01 字符串为每一个字符是 0 或者 1 的字符串,如“101”(不含双引号)为一个长度为 3 的 01 字符串。

输入描述

        共一行,包含一个长度为 8 的 01 字符串 s。

        用例输入 1 

        00010100

        用例输入 2 

        11111111

        用例输入 3 

        01010101

输出描述

        共一行,包含一个整数,即 01 字符串中字符 1 的个数。

        用例输出 1 

        2

        用例输出 2 

        8

        用例输出 3 

        4

答案

#include<bits/stdc++.h>
using namespace std;
char s[80];
int sum;
int main() {
	cin>>s;
	for(int i=0;i<8;i++)
	{
		if(s[i]=='1')
		sum++;
	}
	cout<<sum<<endl;

	return 0;
}

运行结果

公交换乘

时间限制:C/C++ 1000MS,其他语言 2000MS
内存限制:C/C++ 64MB,其他语言 128MB
难度:中等-
分数:100 OI排行榜得分:16(0.1*分数+2*难度)

描述

        著名旅游城市 B 市为了鼓励大家采用公共交通方式出行,推出了一种地铁换乘公交车的优惠方案:
        1、在搭乘一次地铁后可以获得一张优惠票,有效期为 45 分钟,在有效期内可以消耗这张优惠票,免费搭乘一次票价不超过地铁票价的公交车。在有效期内指开始乘公交车的时间与开始乘地铁的时间之差小于等于 45 分钟,即:tbus​−tsubway​≤45
        2、搭乘地铁获得的优惠票可以累积,即可以连续搭乘若干次地铁后再连续使用优惠票搭乘公交车,但每次搭乘公交车只能使用一张优惠券。
        3、搭乘公交车时,如果可以使用优惠票一定会使用优惠票;如果有多张优惠票满足条件,则优先消耗获得最早的优惠票。
现在你得到了小轩最近的公共交通出行记录,你能帮他算算他的花费吗?

输入描述

        第一行包含一个正整数 n,代表乘车记录的数量。
接下来的 n 行,每行包含 3 个整数,相邻两数之间以一个空格分隔。第 i 行的第 1 个整数代表第 i 条记录乘坐的交通工具,0 代表地铁,1 代表公交车;第 2 个整数代表第 i 条记录乘车的票价 pricei ;第三个整数代表第 i 条记录开始乘车的时间 ti​(距 0 时刻的分钟数)。
        我们保证出行记录是按照开始乘车的时间顺序给出的,且 不会有两次乘车记录出现在同一分钟。

        用例输入 1 

        6
        0 10 3
        1 5 46
        0 12 50
        1 3 96
        0 5 110
        1 6 135

        用例输入 2 

        6
        0 5 1
        0 20 16
        0 7 23
        1 18 31
        1 4 38
        1 7 68

输出描述

有一行,包含一个正整数,代表小轩出行的总花费。

        用例输出 1 

        36

        用例输出 2 

        32

提示

数据范围与提示

对于 30% 的数据,n≤1000,ti≤106。
另有 15% 的数据,ti≤107,pricei 都相等。
另有 15% 的数据,ti≤109,pricei 都相等。
对于 100% 的数据,n≤105,ti≤109,1≤pricei≤1000。
注意,本题采用官方比赛实际数据,ti 的真实范围为 ti≤107,特此声明。

样例解释

样例#1:

第一条记录,在第 3 分钟花费 10 元乘坐地铁。
第二条记录,在第 46 分钟乘坐公交车,可以使用第一条记录中乘坐地铁获得的优惠票,因此没有花费。
第三条记录,在第 50 分种花费 12 元乘坐地铁。
第四条记录,在第 96 分钟乘坐公交车,由于距离第三条记录中乘坐地铁已超过 45 分钟,所以优惠票已失效,花费 3 元乘坐公交车。
第五条记录,在第 110 分钟花费 5 元乘坐地铁。
第六条记录,在第 135 分钟乘坐公交车,由于此时手中只有第五条记录中乘坐地铁获得的优惠票有效,而本次公交车的票价为 6 元,高于第五条记录中地铁的票价 5 元,所以不能使用优惠票,花费 6 元乘坐公交车。
总共花费 36 元。

样例#2:

第一条记录,在第 1 分钟花费 5 元乘坐地铁。
第二条记录,在第 16 分钟花费 20 元乘坐地铁。
第三条记录,在第 23 分钟花费 7 元乘坐地铁。
第四条记录,在第 31 分钟乘坐公交车,此时只有第二条记录中乘坐的地铁票价高于本次公交车票价,所以使用第二条记录中乘坐地铁获得的优惠票。
第五条记录,在第 38 分钟乘坐公交车,此时第一条和第三条记录中乘坐地铁获得的优惠票都可以使用,使用获得最早的优惠票,即第一条记录中乘坐地铁获得的优惠票。
第六条记录,在第 68 分钟乘坐公交车,使用第三条记录中乘坐地铁获得的优惠票。
总共花费 32 元。

答案

#include <iostream>
using namespace std;

// 结构体定义
typedef struct ride // 用来记录乘车记录
{
	bool type;
	int price , time;
} rd;

typedef struct discount // 用来记录优惠(免费)票
{
	int getTime = -1 , mon = -1; // 随时清理用过或过期的票,这样就不用used来记录了
} disc;

// 两个数组
rd travel[100005];
disc dis[50];// 只需要45个就够了,因为过期时间是45分钟,题目给出不会有两次车出现在同一分钟,所以最多存储45张优惠票,50是因为设了余量防止溢出

int main()
{
	int n , l = 49 , sum = 0; // l = 49,从后往前存储,这样容易删除过期的票
	cin >> n; // 输入
	for(int i = 0 ; i < n ; i++)
	{
		cin >> travel[i].type >> travel[i].price >> travel[i].time;
		bool flag = false; // 我们可爱的小标记
		//重复清理过期优惠券
		// l要是=49就代表没有优惠券了(别问我大于49是怎样的,自己想想……)
		// 别看是三重循环,速度可比以前快多了
		while(l < 49 && travel[i].time - dis[49].getTime > 45) //当当前优惠券时间过期时就重复执行
		{
			//用for循环将数据向后一项推进,相当于把以前的最后一个覆盖,这也是为什么上面while循环减去的永远是dis[49].getTime
			for(int k = 48 ; k > l ; k--)
			{
				dis[k+1].getTime = dis[k].getTime;
				dis[k+1].mon = dis[k].mon;
			}
			// 并将之前最新的优惠券那里填上-1
			dis[l+1].getTime = -1;
			dis[l++].mon = -1;
		}
		// 当坐地铁时
		if(!travel[i].type)
		{
			// 累加
			sum += travel[i].price;
			// 记录
			dis[l].getTime = travel[i].time;
			dis[l--].mon = travel[i].price;
		}
		// 当坐公交车时
		else
		{
			// j不用再从0到j了,剩下了很多时间
			for(int j = 49 ; j > l ; j--)
			{
				// 简单的小判断,判断钱数超没超
				if(travel[i].price <= dis[j].mon)
				{
					// 没有接使用并标记,再将其前面的优惠券向前推进,从而覆盖这个优惠券,相当于删除
					flag = true;
					for(int k = j-1 ; k > l ; k--)
					{
						dis[k+1].getTime = dis[k].getTime;
						dis[k+1].mon = dis[k].mon;
					}
					dis[l+1].getTime = -1;
					dis[l++].mon = -1;
					// 撒由哪啦┏(^0^)┛
					break;
				}
			}
			// 没标记就累加
			if(!flag)
			{
				sum += travel[i].price;
			}
		}
	}
	// 输出结果……
	cout << sum << endl;
 	return 0;
}

 运行结果

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值