P8791 [蓝桥杯 2022 国 AC] 内存空间 题解
题面
一道比较简单模拟题,但是要分类讨论
一.读完题你应该知道的
1.输入一共有 T + 1
行,输入含有空格。(处理1)
2.对于每一行变量定义的语句,只会出现一种变量类型,type
只可能是 int
或 long
,只有一个分号。(处理1,处理2)
3.统计内存过程中用 B
做单位,保证一定有输出,但在输出时要换算。(比如1024
B就要换算成1
KB)(处理3)
4.即使用 int
或 long
定义的 a = 0
也会占用空间。(处理2)
二.解法 (不就是模拟吗)
处理1
通过题目和样例可以看出,接下来的T行,每次定义都会先声明本行的变量类型(这一部分不含空格,且后面会紧接着一个空格),包括 int
,int[]
,long
,long[]
和 String
(注意这里的S
是大写)。
因此 , 可以先定义一个 string s
,然后 cin >> s
,只记录下这一行所声明的变量,然后再分类讨论做处理。
处理2
处理2.0
完成处理1后,后面还有一长串需要输入,这时候对于 int[]
, long[]
和 String
就需要用 getline
来输入,从样例可以看出,不保证没有空格,所以用 getline
保险起见。(其实不用就会WA)
而对于 int
和 long
类型,题目保证没有多余的空格,用的人都知道,只需要 cin >> s
就够了。
2.1对于 int
和 long
类型
对于这种类型,可以发现,它们定义时一定是形如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
考虑题目内存所占空间是( 0B
,1024GB
),即( 0B
,1,099,511,627,776B
),用 int
来存一定会炸,所以这里用 long long
定义 4
个变量 GB
,MB
,KB
,B
进行储存。并且在每一行的操作结束后,都对这 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;
}