写在前面:这里是小王成长日志,一名在校大学生,想在学习之余将自己的学习笔记分享出来,记录自己的成长轨迹,帮助可能需要的人。欢迎关注与留言。
试题 : REPEAT 程序
本题总分:10 分
【问题描述】
附件 prog.txt 中是一个用某种语言写的程序。(prog文件点击这里)
其中 REPEAT k 表示一个次数为 k 的循环。循环控制的范围由缩进表达,
从次行开始连续的缩进比该行多的(前面的空白更长的)为循环包含的内容。
例如如下片段:
(!!!这里只是个示例,不是让我们求下面这个片段的结果,答案403的该擦擦眼睛了)
REPEAT 2:
A = A + 4
REPEAT 5:
REPEAT 6:
A = A + 5
A = A + 7
A = A + 8
A = A + 9
该片段中从 A = A + 4 所在的行到 A = A + 8 所在的行都在第一行的
循环两次中。
REPEAT 6: 所在的行到 A = A + 7 所在的行都在 REPEAT 5: 循环中。
A = A + 5 实际总共的循环次数是 2 × 5 × 6 = 60 次。
请问该程序执行完毕之后,A 的值是多少?
【答案提交】
这是一道结果填空题,你只需要算出结果后提交即可。本题的结果为一个
整数,在提交答案时只填写这个整数,填写多余的内容将无法得分。
解题
思路:
首先,如果代码所给的文件比较小,就像上面给的示例,完全可以手写for循环实现,然后看结果,但是他给的文件总共1001行,同时要考虑缩进导致的大括号,使用c/c++手动实现的话最后代码数量会达千行,得不偿失且容易出错。
这道题乍看没有头绪,但天无绝人之路,他的循环体非常的简单,而且可以把循环的加法变成一个乘法,例如下面的代码就等价于a=4*2+5*2*5*6。
REPEAT 2:
A = A + 4//4*2
REPEAT 5:
REPEAT 6:
A = A + 5//5*(2*5*6)
因此我们就可以考虑使用一个数组去记录他的循环次数,一旦遇到A=A+X这样的语句就将X乘上前面的循环次数然后加回到A上。
以下为代码实现,具体的思路代码中都有注释,如有不懂可以留言:
#include <iostream>
#include <string.h>
using namespace std;
int ctn(char n);
//附件 prog 很长
// 建议现场用Python做 --python也是依靠缩进进行判断的 进行简单的cf文本替换就可以了
//c文件处理
int main(){
//打开并读取文件
FILE *fp=NULL;
char buff[255];
char src[]="F:/001蓝桥/file/prog.txt";
fp=fopen(src,"r");
// cout<<"文件读取成功"<<endl;
//缩进控制数组
int fact[10];
int head=0;//head头指针表示当前循环层级
int a=0,i;
fgets(buff,255,(FILE*)fp);//先跳过第一行
//循环读取文件每一行
while(fgets(buff,255,(FILE*)fp)){
// cout<<buff;
int p=0;
while(buff[p]==' ') p++;
if(buff[p]=='R'){
head=(p==0?0:p/4);//根据缩进判断层级
fact[head]=ctn(buff[p+7]);
continue;
}
else if(buff[p]=='A'){
head=(p==0?-1:p/4-1);//注意:第一个字母就是A的情况下 他是不在任何循环里的!
/**
A = A + 8
A = A + 9//这句
*/
int fa=1;
if(p!=-1)//只有在循环里才执行
for(i=0;i<=head;i++)
fa*=fact[i];
a+=fa*ctn(buff[p+8]);
}
}
cout<<a;
return 0;
}
//字符转数字
int ctn(char n){
switch(n){
case('1'): return 1;
case('2'): return 2;
case('3'): return 3;
case('4'): return 4;
case('5'): return 5;
case('6'): return 6;
case('7'): return 7;
case('8'): return 8;
case('9'): return 9;
}
}
如果以上内容有任何不准确或遗漏之处,或者你有更好的意见,就在下面留个言让我知道吧-我会尽我所能来回答。