题目地址:http://www.nocow.cn/index.php/Translate:USACO/crypt1
从今天开始,有时间的话,至少做到每天破两题。简单的也就快一点。
今天的题比较简单,也比较粗暴。感觉在上一届的蓝桥杯遇到过类似的题型。爆搜。恐怖的5个循环。
今天学到一种新的方法,hash函数的方法。不仅思路清晰了,编码的速度也很快。很好用。
1、将合法的数字标记;
2、利用取余数操作取数字判断;
3、根据数据范围,穷举数字,同时判断其是否符合题目的要求;
下面先列出我开始思考的方法:
没有写完:
/*
思路1
1、两个因数,五个位置,分别穷举。
2、乘出来的数字分别检查,长度,是否在所给数字中;
3、加和之后,再判断长度,所给数字;
*/
#include <stdio.h>
//判断是否在所给数字之内 ,num限定数字的个数,len限定的长度
int check(int *given,int num,int get,int len)
{
int temp;
int i;
int count=0;
while( get != 0)
{
temp= get%10;
get = get/10;
for(i=0 ; i< num && temp != given[i];i++);
if( i==num)
{
return 0;
}
count++;
}
//判断数字长度
if( count > len)
{
return 0;
}
return 1;
}
int main()
{
int n;
int input[10];
int i;
for(i=0 ; i< n;i++)
{
scanf("%d",&input[i]);
}
int q,w,e,r,t;
for(q=0 ; q < n;q++)
{
for( w=0 ; w<n;w++)
{
for(e=0 ; e < n;e++)
{
for( r=0 ; r<n;r++)
{
for( t=0 ; t<n;t++)
{
…………//判断函数,加,乘判断。
}
}
}
}
}
return 0;
}
下面是改进后的hash函数方法。算法复杂度O(1)
//利用hash函数判断
#include <stdio.h>
int hash[10];
//合理1;不合理0
int check(int x)
{
while(x!=0)
{
if( hash[x%10] ==0)return 0;
x /= 10;
}
return 1;
}
int main()
{
int n;
int input[10];
scanf("%d",&n);
int i;
for(i=0 ;i< n;i++)
{
scanf("%d",&input[i]);
//可以使用的数字,标记
hash[input[i]]=1;
}
int abc,de;
int count=0;
for(abc=111 ; abc < 1000 ; abc++)
{
//该数合法
if( check(abc) == 1)
{
for( de=11; de < 100 ; de++)
{
//该数合法
if( check(de) ==1)
{
//两数之机大于四位数,跳出 ;机的数判断
if( de*abc > 9999 || check(de*abc)==0)continue;
//分部乘,第一部分判断
if( check(abc*(de%10)) ==0 )continue;
if( abc*(de%10)<100 || abc*(de%10) > 999 )continue;
//分部乘,第二部分判断
if( check(abc*(de/10))==0)continue;
if( abc*(de/10)<100 || abc*(de/10) > 999 )continue;
count++;
}
}
}
}
printf("%d",count);
return 0;
}