题解 P4346 【[CERC2015]ASCII Addition】
萌新刚从
我发现这样一种简洁的思路,因为每个点都是
然后把二进制再转回十进制,就可以得到0
最后把读入的矩阵分别转成十进制,再去找提前准备好的十进制数,对应一下得到0
最后把这些数拼起来运算一下,把对应的
小问题:一开始我以为会有多个“+”,于是计算总和的写法有点奇怪
#include <bits/stdc++.h>
using namespace std;
string s[11];
int a[30][1000],x,num,t,cnt;
char m[30][1000];
int b[30],ans[30],dt[30],d[30];
int c[11]={
1363481695,272696336,1098712095,276628511,276632657,276566111,1367085151,272696351,1367151711,276632671,75251968
};//提前准备0~9和“+”对应的矩阵转成二进制的值(也是通过这个程序算出的)
string e[10]={
("xxxxxx...xx...xx...xx...xx...xxxxxx"),
("....x....x....x....x....x....x....x"),
("xxxxx....x....xxxxxxx....x....xxxxx"),
("xxxxx....x....xxxxxx....x....xxxxxx"),
("x...xx...xx...xxxxxx....x....x....x"),
("xxxxxx....x....xxxxx....x....xxxxxx"),
("xxxxxx....x....xxxxxx...xx...xxxxxx"),
("xxxxx....x....x....x....x....x....x"),
("xxxxxx...xx...xxxxxxx...xx...xxxxxx"),
("xxxxxx...xx...xxxxxx....x....xxxxxx"),
};//提前准备0~9对应的ASCII矩阵(长5 宽7)
int main(){
for (int i=1;i<=7;i++){
cin>>s[i];
s[i]=s[i]+'.';
}//为了确保最后一个数的二进制位数与前面的一样,所以在每行末尾加个“.”
int n=s[1].length();
for (int i=1;i<=7;i++)
for (int j=0;j<n;j++){
a[i][j]=(s[i][j]=='x');//转二进制,“x”为1,“.”为0
}
t=1;
for (int i=0;i+6<=n;i+=6){//把矩阵当做一维处理
x=1;
for (int j=1;j<=7;j++)
{//二进制转十进制
for (int k=i;k<i+6;k++)
{
b[num]+=x*a[j][k];
x=x*2;
}
}
for (int j=0;j<10;j++)
if (b[num]==c[j]){
ans[t]=ans[t]*10+j;
break;
}
if (b[num]==75251968) t++;//特判加号
num++;
}
for (int i=1;i<=t;i++) ans[t+1]+=ans[i];
while(ans[t+1]!=0){//取出答案(十进制)的每一位数
cnt++;
dt[cnt]=ans[t+1]%10;
ans[t+1]=ans[t+1]/10;
}
for (int i=1;i<=cnt;i++) d[i]=dt[cnt-i+1];
for (int i=0;i<35;i+=5){//输出参考了大佬的写法
for (int j=1;j<=cnt;j++)
{
for (int k=i;k<=i+4;k++)
printf("%c",e[d[j]][k]);
if (j!=cnt) printf(".");
}
printf("\n");
}
return 0;
}