九个点
每个点只能连一次 ,如果两个点AB之间有其他点C,在C点被使用之前AB不能直接相连
两种解法
一种是直接用简单的9个循环
#include <stdio.h>
int main(){
int count=0;
for(int i1=1; i1<10; i1++){
for(int i2=1; i2<10; i2++){
if(i2 == i1) continue;
if((i2+i1)%2 ==0 ){
int mid=(i1+i2)/2;
if(mid == 2 || mid== 8 || mid == 5) continue;
if(mid == 4 && (i2 == 1 || i2 == 7)) continue;
if(mid == 6 && (i2 == 3 || i2 == 9)) continue;
}
for(int i3=1; i3<10; i3++){
if(i3 == i1 || i3 == i2) continue;
if((i2+i3)%2 ==0 ){
int mid=(i3+i2)/2;
if((mid == 2 || mid== 8 || mid == 5) && mid != i1) continue;
if(mid == 4 && i1 != 4 && (i3 == 1 || i3 == 7)) continue;
if(mid == 6 && i1 != 6 && (i3 == 3 || i3 == 9)) continue;
}
for(int i4=1; i4<10; i4++){
if(i4 == i1 || i4 == i2 || i4 == i3) continue;
if((i3+i4)%2 ==0 ){
int mid=(i3+i4)/2;
if((mid == 2 || mid== 8 || mid == 5) && mid != i1 && mid != i2) continue;
if(mid == 4 && i1 != 4 && i2!=4 && (i4 == 1 || i4 == 7)) continue;
if(mid == 6 && i1 != 6 && i2!=6 && (i4 == 3 || i4 == 9)) continue;
}
for(int i5=0; i5<10; i5++){
if(i5 == i1 || i5 == i2 || i5 == i3 || i5 == i4 ) continue;
if( i5!= 0 && (i4+i5)%2 ==0 ){
int mid=(i4+i5)/2;
if((mid == 2 || mid== 8 || mid == 5) && mid != i1 && mid != i2 && mid != i3) continue;
if(mid == 4 && i1 != 4 && i2!=4 && i3!=4 && (i5 == 1 || i5 == 7)) continue;
if(mid == 6 && i1 != 6 && i2!=6 && i3!=6 && (i5 == 3 || i5 == 9)) continue;
}
if(i5 == 0){
printf("%d\t%d%d%d%d\n",count+1, i1,i2,i3,i4);
count++;
}else{
for(int i6=0; i6<10; i6++){
if( i6 == i1 || i6 == i2 || i6 == i3 || i6 == i4 || i6 == i5) continue;
if( i6 != 0 && (i5+i6)%2 ==0 ){
int mid=(i5+i6)/2;
if((mid == 2 || mid== 8 || mid == 5) && mid != i1 && mid != i2 && mid != i3 && mid !=i4) continue;
if(mid == 4 && i1 != 4 && i2!=4 && i3!=4 && i4!=4 && (i6 == 1 || i6 == 7)) continue;
if(mid == 6 && i1 != 6 && i2!=6 && i3!=6 && i4!=6 && (i6 == 3 || i6 == 9)) continue;
}
if(i6 == 0){
printf("%d\t%d%d%d%d%d\n", count + 1, i1, i2, i3, i4, i5);
count++;
}else{
for(int i7=0; i7<10; i7++){
if(i7 == i1 || i7 == i2 || i7 == i3 || i7 == i4 || i7 == i5 || i7 == i6) continue;
if(i7!=0 && (i6+i7)%2 ==0 ){
int mid=(i6+i7)/2;
if((mid == 2 || mid== 8 || mid == 5) && mid != i1 && mid != i2 && mid != i3 && mid !=i4 && mid !=i5) continue;
if(mid == 4 && i1 != 4 && i2!=4 && i3!=4 && i4!=4 && i5!=4 && (i7 == 1 || i7 == 7)) continue;
if(mid == 6 && i1 != 6 && i2!=6 && i3!=6 && i4!=6 && i5!=6 && (i7 == 3 || i7 == 9)) continue;
}
if(i7 == 0){
printf("%d\t%d%d%d%d%d%d\n", count + 1, i1, i2, i3, i4, i5, i6);
count++;
}else{
for(int i8=0; i8<10; i8++){
if(i8 == i1 || i8 == i2 || i8 == i3 || i8 == i4 || i8 == i5 || i8 == i6 || i8==i7) continue;
if(i8!= 0 && (i7+i8)%2 ==0 ){
int mid=(i7+i8)/2;
if((mid == 2 || mid== 8 || mid == 5) && mid != i1 && mid != i2 && mid != i3 && mid !=i4 && mid !=i5 && mid!=i6 ) continue;
if(mid == 4 && i1 != 4 && i2!=4 && i3!=4 && i4!=4 && i5!=4 && i6!= 4 && (i8 == 1 || i8 == 7)) continue;
if(mid == 6 && i1 != 6 && i2!=6 && i3!=6 && i4!=6 && i5!=6 && i6!= 6 && (i8 == 3 || i8 == 9)) continue;
}
if(i8 == 0){
printf("%d\t%d%d%d%d%d%d%d\n", count + 1, i1, i2, i3, i4, i5, i6, i7);
count++;
}else{
for(int i9=0; i9<10; i9++){
if(i9 == i1 || i9 == i2 || i9 == i3 || i9 == i4 || i9 == i5 || i9 == i6 || i9==i7 || i9 == i8 ) continue;
if(i9 == 0){
printf("%d\t%d%d%d%d%d%d%d%d\n", count + 1, i1, i2, i3, i4, i5, i6, i7, i8);
count++;
}else{
printf("%d\t%d%d%d%d%d%d%d%d%d\n", count + 1, i1, i2, i3, i4, i5, i6, i7, i8, i9);
count++;
}
}
}
}
}
}
}
}
}
}
}
}
}
}
printf("\ntotal:%d\n", count);
return 0;
}
额,看着头疼
一种是用回溯法
#include <stdio.h>
#define bool int
#define true 1
#define false 0
int ptn[10];
int index[10];
bool used[10];
int len;
int total;
void ini()
{
int i;
len = 1;
total = 0;
for (i = 0; i < 10; i++)
{
ptn[i] = 9;
index[i] = 1;
used[i] = false;
}
}
bool CanUse(int len, int num)
{
int i;
if (len == 0)
return false;
for (i = 0; i < 9; i++)
used[i] = false;
for (i = 0; i < len - 1; i++)
used[ptn[i] - 1] = true;
if (used[num - 1])
return false;
int prenum, mid;
prenum = ptn[len - 2];
if (num == 5 || prenum == 5)
return true;
mid = (prenum + num) / 2;
if (prenum % 2 == 1 && num % 2 == 1)
{
return used[mid - 1];
}
else if (prenum % 2 == 0 && num % 2 == 0)
{
if (mid == 5)
return used[5 - 1];
}
return true;
}
int GetNum(int len)
{
int i;
for (i = index[len - 1]; i <= 9; i++)
{
if (CanUse(len, i))
break;
}
return i;
}
bool Next()
{
int num;
do
{
num = GetNum(len);
while (num == 10)//
{
index[len - 1] = 1;
if (len > 1) index[len - 2] ++;
len--;
num = GetNum(len);
if (len == 1 && num == 10 )
return false;
}
ptn[len - 1] = num;
index[len - 1] = num;
len++;
used[num] = true;
return true;
} while (len > 0);
return false;
}
void print()
{
int i;
if (len <= 4)
return;
total++;
printf("%d\t",total);
for (i = 0; i < len - 1; i++)
{
printf("%d",ptn[i]);
}
printf("\n");
}
int main()
{
ini();
int t;
while (Next())
{
print();
}
printf("%d\t", total);
return 0;
}
效率第一种明显比第二种高,大约快了三倍
在编程上来说,第一种速度较快,一个同事大概20分钟搞定
好几年没编程了,搞了两天才搞定,
编译后第一个程序8.5k,第二个7k
个人感觉效率快慢原因在于一是第二个函数调用多,二是第一个程序把许多判断都固化了。也不知道对不对,有高人能分析一下两个程序效率吗?
结果都一样 ,共有 389112种解锁图案。
这篇博客探讨了Android设备上解锁图案的可能种类。通过两种不同的编程方法——简单循环和回溯法,博主计算出共有389,112种不同的解锁图案。尽管回溯法程序的编译大小较小,但博主认为由于更多的函数调用,其效率可能较低于直接循环的方法。"
116796711,10545599,Linux命令行连接远程DB2数据库指南,"['数据库管理', 'Linux命令行', 'DB2数据库']
3万+

被折叠的 条评论
为什么被折叠?



