P8791 [蓝桥杯 2022 国 AC] 内存空间 题解

题面

一道比较简单模拟题,但是要分类讨论

一.读完题你应该知道的

1.输入一共有 T + 1 行,输入含有空格。(处理1)

2.对于每一行变量定义的语句,只会出现一种变量类型,type 只可能是 intlong ,只有一个分号。(处理1,处理2)

3.统计内存过程中用 B 做单位,保证一定有输出,但在输出时要换算。(比如1024B就要换算成1KB)(处理3)

4.即使用 intlong 定义的 a = 0 也会占用空间。(处理2)


二.解法 (不就是模拟吗)

处理1

通过题目和样例可以看出,接下来的T行,每次定义都会先声明本行的变量类型(这一部分不含空格,且后面会紧接着一个空格),包括 intint[]longlong[]String (注意这里的S是大写)。

因此 , 可以先定义一个 string s ,然后 cin >> s ,只记录下这一行所声明的变量,然后再分类讨论做处理。


处理2

处理2.0

完成处理1后,后面还有一长串需要输入,这时候对于 int[]long[]String 就需要用 getline 来输入,从样例可以看出,不保证没有空格,所以用 getline 保险起见。(其实不用就会WA)

而对于 intlong 类型,题目保证没有多余的空格,用的人都知道,只需要 cin >> s 就够了。

2.1对于 intlong 类型

对于这种类型,可以发现,它们定义时一定是形如a=b的形式,当有多个这样的形式存在时用逗号隔开,结尾以分号结束。只需要遍历一遍整个字符串,并统计其中 "=" 出现的次数即可,由于这里只是定义了一个变量,总值只需要加上 4B (int 类型) 或 8B ( long 类型) 就行了。

2.2对于 int[]long[] 类型

遍历声明了 int[] 类型或 long[] 类型的这一行时,定义一个标记变量\(l\),来标记所遇到的 [ 的下一个位置,也就是 [ 右边的第一个数字,当遇到 ] 时,说明这一个数组定义已经完成,再从 l 开始到 i - 1 的位置进行遍历,将数组大小\(k\)取出来,最后总值加上 k * 4 ( int 类型) 或 k * 8 ( long 类型) 即可。

2.3对于 String 类型

跟上面的差不多,但是英文输入中的双引号长得是一样的,在遍历声明了 String 类型的这一行时,先定义标记变量 flag 来标记在第 j 个位置第 i (此时 i 为奇数) 次遇到的 "后一个位置,也就是第 j + 1 个位置,在第 i + 1 次遇到 " 时,用当前的位置 j ,即 j 减去 flag ,也就是 j - flag ,得出的结果 k 就是这一段字符串的长度。字符串中每个字符只占用 1B ,最后总值加上 k 即可。

对于整个处理2,其实可以用函数模块化解决,代码量会大大缩减。


处理3

考虑题目内存所占空间是( 0B1024GB ),即( 0B1,099,511,627,776B ),用 int 来存一定会炸,所以这里用 long long 定义 4 个变量 GBMBKBB 进行储存。并且在每一行的操作结束后,都对这 4 个变量进行及时的维护。(其实好像没有必要,在最后维护一次就够了)


最后贴上我码风奇特的代码:

#include<bits/stdc++.h>
#define ll long long
#define maxx 1000100
#define fr(i , a , b) for(ll i = a ; i <= b ; ++i)
#define fo(i , a , b) for(ll i = a ; i >= b ; --i)
using namespace std;
inline ll read()
{
	ll k = 0 , f = 0;
	char c = getchar();
	for( ; !isdigit(c) ; c = getchar())
	{
		f |= c == '-';
	}
	for( ; isdigit(c) ; c = getchar())
	{
		k = (k << 1) + (k << 3) + (c ^ 48);
	}
	return f ? -k : k;
}
ll T , GB , MB , KB , B;
string s;
signed main()
{
	T = read();
	while(T--)
	{
		cin >> s;
		if(s == "int")
		{	
//			getline(cin , s);
			cin >> s;
			ll kkk = 0;
			fr(i , 0 , s.size() - 1)
			{
				if(s[i] == '=')
				{
					kkk++;
				}
			}
			B += kkk * 4;
			KB += B / 1024;
			B %= 1024;
			MB += KB / 1024;
			KB %= 1024;
			GB += MB / 1024;
			MB %= 1024;
		}
		else if(s == "int[]")
		{
			getline(cin , s);
			ll l;
			fr(i , 0 , s.size() - 1)
			{
				if(s[i] == '[')
				{
					l = i + 1;
				}
				else if(s[i] == ']')
				{
					ll kkk = 0;
					fr(j , l , i - 1)
					{
						kkk = kkk * 10 + (s[j] - '0');
					}
					B += kkk * 4;
				}
			}
			KB += B / 1024;
			B %= 1024;
			MB += KB / 1024;
			KB %= 1024;
			GB += MB / 1024;
			MB %= 1024;
		}
		else if(s == "long")
		{
//			getline(cin , s);
			cin >> s;
			ll kkk = 0;
			fr(i , 0 , s.size() - 1)
			{
				if(s[i] == '=')
				{
					kkk++;
				}
			}
			B += kkk * 8;
			KB += B / 1024;
			B %= 1024;
			MB += KB / 1024;
			KB %= 1024;
			GB += MB / 1024;
			MB %= 1024;
		}
		else if(s == "long[]")
		{
			getline(cin , s);
			ll l;
			fr(i , 0 , s.size() - 1)
			{
				if(s[i] == '[')
				{
					l = i + 1;
				}
				else if(s[i] == ']')
				{
					ll kkk = 0;
					fr(j , l , i - 1)
					{
						kkk = kkk * 10 + (s[j] - '0');
					}
					B += kkk * 8;
				}
			}
			KB += B / 1024;
			B %= 1024;
			MB += KB / 1024;
			KB %= 1024;
			GB += MB / 1024;
			MB %= 1024;
		}
		else
		{
			ll flag = -1;
			cin >> s;
			fr(i , 0 , s.size() - 1)
			{
				if(s[i] == '"' && flag == -1)
				{
					flag = i + 1;
					continue;
				}
				if(s[i] == '"' && flag != -1)
				{
					B += i - flag;
					flag = -1;
				} 
			}
			KB += B / 1024;
			B %= 1024;
			MB += KB / 1024;
			KB %= 1024;
			GB += MB / 1024;
			MB %= 1024;
		}
	}
	if(GB != 0)
	{
		printf("%lldGB" , GB);
	}
	if(MB != 0)
	{
		printf("%lldMB" , MB);
	}
	if(KB != 0)
	{
		printf("%lldKB" , KB);
	}
	if(B != 0)
	{
		printf("%lldB" , B);
	}
	return 0;
}
posted @ 2024-04-10 21:44  心海秋的墨木仄  阅读(15)  评论(0编辑  收藏  举报