题解 P1211 【[USACO1.3]牛式 Prime Cryptarithm 】
ShineEternal
2019-07-07 19:07:22
这题也调了好久,记录一下收获,顺便提醒一下后人。。。
# 分析:
这道题思路是枚举每一种竖式,这个没什么,主要是里面的判断:
- 刚开始要判断循环到的i,j在不在给定数列里(好吧这个我知道)
- 然后要判断乘出来的所有数在不在给定数列里(这个我忘考虑了,最后观察输出才想起来,检查过程详见注释)
- 还要判断乘出来的数字位数与原题对不对应(这个显然)
**下面就可以上代码了,check函数是判断在不在给定数列的,然鹅刚开始的第一步判断因为没有想到第二步,所以就没有写到函数里,最后就不想改了QAQ**
> code:
```cpp
#include<cstdio>
using namespace std;
int a[105],tmp[10],ls[105];
int n;
int check(int x)
{
int cnt=0;
while(x)
{
ls[++cnt]=x%10;
x=x/10;
}
for(int i=1;i<=cnt;i++)
{
int flag=0;
for(int j=1;j<=n;j++)
{
if(ls[i]==a[j])
{
flag=1;
break;
}
}
if(flag==0)return 0;
}
return 1;
}
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
scanf("%d",&a[i]);
}
int ans=0;
for(int i=100;i<=999;i++)
{
for(int j=10;j<=99;j++)
{
int k=i,upf=0,cnt=0,flag;
while(k)
{
tmp[++cnt]=k%10;
k/=10;
}
for(int k=1;k<=cnt;k++)
{
flag=0;
for(int h=1;h<=n;h++)
{
if(tmp[k]==a[h])
{
flag=1;
break;
}
}
if(flag==0)
{
upf=1;
break;
}
}
if(upf==1)
continue;
k=j,upf=0,cnt=0;
while(k)
{
flag=0;
tmp[++cnt]=k%10;
k/=10;
}
for(int k=1;k<=cnt;k++)
{
flag=0;
for(int h=1;h<=n;h++)
{
if(tmp[k]==a[h])
{
flag=1;
break;
}
}
if(flag==0)
{
upf=1;
break;
}
}
if(upf==1)
continue;
int x=j%10;
int y=(j/10)%10;
int xx=i*x;
int yy=i*y;
int z=xx+yy*10;
//printf("%d %d %d %d %d\n",i,j,xx,yy,z);
cnt=0;
if(check(xx)==0)continue;
while(xx)
{
cnt++;
xx=xx/10;
}
if(cnt!=3)
continue;
cnt=0;
if(check(yy)==0)continue;
while(yy)
{
cnt++;
yy=yy/10;
}
if(cnt!=3)
continue;
cnt=0;
if(check(z)==0)continue;
while(z)
{
cnt++;
z=z/10;
}
if(cnt!=4)
continue;
//printf("ds\n");
ans++;
}
}
printf("%d\n",ans);
return 0;
}
```