1 条题解
-
0
自动搬运
来自洛谷,原作者为

DFs_YYDS
明年不拿绿勾就再也别换个签了 || 擅长的是线下物理单杀而不是对线||上帝给我关了一扇门,但是我把门炸掉了 || 毁灭你,与你何关?搬运于
2025-08-24 21:16:20,当前版本为作者最后更新于2024-06-08 07:46:46,作者可能在搬运后再次修改,您可在原文处查看最新版自动搬运只会搬运当前题目点赞数最高的题解,您可前往洛谷题解查看更多
以下是正文
题目大意
给你红绿灯在显示 次数字时,亮了哪些数码管,问你这些数码管有没有常亮(即无论什么数字都会亮)或不亮(即无论什么数字都不亮)。
方法一(不推荐)
具体思路
按照题意模拟。
条日志,对于每条日志,首先处理常亮的情况。如果显示这个数字不需要显示该数码管,但是数码管亮了,就说明它是常亮的。然后再处理不亮的情况,如果显示这个数字需要显示该数码管,但是数码管没亮,就说明它是不亮的,将每个数码管的情况用一个 数组存起来,最后输出即可。
完整代码
#include<bits/stdc++.h>//万能头。 using namespace std; char ans[10];//数码管的状态,由于题目中说常亮用大写X,不亮用小写x,没发现故障用-,所以用字符数组来表示。 string book[10]={"ABCDEF ","BC ","ABGED ","ABGCD ","FGBC ","AFGCD ","AFDECG ","ABC ","ABCDEFG ","ABCDFG "};//book[i]表示显示第i个数需要显示的数码管编号。 int main(){//主函数。 int n;//n次记录。 cin>>n;//输入n。 for(int i=0;i<7;i++)ans[i]='-';//刚开始将7个数码管的状态初始化为-,没发现任何故障。 while(n--){//循环n次。 string s;//由于日志是由数字和字母组成的,中间又没有空格,所以用字符串存储比较方便。 cin>>s;//输入字符串s。 int x=s[0]-'0'/*本次记录的数字*/,len=s.size()/*字符串的长度*/; //处理常亮的情况。 for(int i=1;i<len;i++){//循环这次记录的字符串,注意从1开始,因为前面还有一位是数字。 int flag=1;//是否损坏。 for(int j=0;book[x][j]!=' ';j++){//由于显示每个数字需要的数码管不一样,所以统一最后有一个空格。 if(book[x][j]==s[i]){//如果这个数码管本来就需要亮。 flag=0;//没有损坏。 break;//直接跳出循环,减少时间。 } } if(flag)/*如果这个数码管不需要亮,但它亮了*/ans[s[i]-'A']='X';//这个数码管的状态就是常亮。 } //处理不亮的情况。 for(int i=0;book[x][i]!=' ';i++){//循环显示x需要的数码管,遇到空格结束。 int flag=1;//是否损坏。 for(int j=1;j<len;j++){//循环日志中记录的亮的数码管,注意从1开始。 if(book[x][i]==s[j]){//如果这个数码管在记录中确实亮了。 flag=0;//没有损坏。 break;//跳出循环。 } } if(flag)/*如果这个数码管需要亮,但它没亮*/ans[book[x][i]-'A']='x';//这个数码管的状态就是不亮。 } } for(int i=0;i<7;i++)cout<<ans[i];//输出ans数组。 return 0;//好习惯。 }但是代码未免有些太长了,怎么缩短呢?
方法二(推荐)
具体思路
方法一代码长的原因在于,用了两个循环双重循环分别处理常亮和不亮的情况,如果我们将常亮和不亮在同一个循环中一起处理,代码就会缩短很多。
参考方法一,使用数组把显示每个数字需要亮的数码管存起来。但是跟方法一不一样的是,我们用的是
int的二维数组(bool也行)来存。 表示在显示数字 时第 个数码管是否需要亮,如果是 表示需要亮,如果是 表示不需要亮。同样,在 个日志中。先建一个数组 , 表示第 个数码管是否亮了。然后循环每个数码管,如果 为 但 为 ,也就是说第 个数码管不应该亮但是亮了,这个数码管就是常亮的;如果 为 但 为 ,也就是说第 个数码管应该亮但是没亮,这个数码管就是不亮的,将状态存入答案数组 中。
这样,我们就将两个循环缩减为一个循环,大大的减少了代码量。
完整代码
#include<bits/stdc++.h> using namespace std; char ans[10];//答案数组。 int book[10][7]={1,1,1,1,1,1,0, 0,1,1,0,0,0,0, 1,1,0,1,1,0,1, 1,1,1,1,0,0,1, 0,1,1,0,0,1,1, 1,0,1,1,0,1,1, 1,0,1,1,1,1,1, 1,1,1,0,0,0,0, 1,1,1,1,1,1,1, 1,1,1,1,0,1,1,}; int main(){ int n; cin>>n; for(int i=0;i<7;i++)ans[i]='-';//初始化。 for(int i=0;i<n;i++){ string s; cin>>s; int x=s[0]-'0',len=s.size(); int a[10];//实际上a数组开到7就行了,这里开10保险一点。 for(int j=0;j<7;j++)a[j]=0;//在循环内定义数组要先全部初始化为0。 for(int j=1;j<len;j++)a[s[j]-'A']=1;//这个数码管亮了。 for(int j=0;j<7;j++){ if(a[j]==1&&book[x][j]==0)ans[j]='X';//如果这个数码管亮了但是实际上不应该亮,这个数码管就是常亮的。 if(a[j]==0&&book[x][j]==1)ans[j]='x';//如果这个数码管没亮但是实际上应该亮,这个数码管就是不亮的。 } } for(int i=0;i<7;i++)cout<<ans[i];//输出答案数组。 return 0;//华丽结束。 }如果你还觉得长是因为 数组的原因,我们将 数组放到一行,就不觉得长了。
最终完整代码
#include<bits/stdc++.h> using namespace std; char ans[10];//答案数组。 int book[10][7]={1,1,1,1,1,1,0,0,1,1,0,0,0,0,1,1,0,1,1,0,1,1,1,1,1,0,0,1,0,1,1,0,0,1,1,1,0,1,1,0,1,1,1,0,1,1,1,1,1,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,1,1,}; int main(){ int n; cin>>n; for(int i=0;i<7;i++)ans[i]='-';//初始化。 for(int i=0;i<n;i++){ string s; cin>>s; int x=s[0]-'0',len=s.size(); int a[10];//实际上a数组开到7就行了,这里开10保险一点。 for(int j=0;j<7;j++)a[j]=0;//在循环内定义数组要先全部初始化为0。 for(int j=1;j<len;j++)a[s[j]-'A']=1;//这个数码管亮了。 for(int j=0;j<7;j++){ if(a[j]==1&&book[x][j]==0)ans[j]='X';//如果这个数码管亮了但是实际上不应该亮,这个数码管就是常亮的。 if(a[j]==0&&book[x][j]==1)ans[j]='x';//如果这个数码管没亮但是实际上应该亮,这个数码管就是不亮的。 } } for(int i=0;i<7;i++)cout<<ans[i];//输出答案数组。 return 0;//完结撒花! }
- 1
信息
- ID
- 10321
- 时间
- 1000ms
- 内存
- 512MiB
- 难度
- 2
- 标签
- 递交数
- 0
- 已通过
- 0
- 上传者