N Queen Again LightOJ - 1061

Keywords: C++

N Queen Again LightOJ - 1061

Firstly, all the eight queens'solutions (only 92) are given by pretreatment (or tabulation). Then enumerate the target state, and use a shape pressure dp for each target state to find the minimum cost of reaching that state. The minimum cost of reaching any target state is the answer.

Obviously, if we know the position of the original 8 points, we will reach the position of the target 8 points, which is to make each original point match a target point. Why do you think of exploding when you see it? But there's something better than exploding.

The shape pressure dp is:

ans[S] represents the minimum cost of matching the previous | S | (the number of points in the S set) points in the original point with [all target points satisfying the condition that the number is included in the S set].

For each enumerated S, the point to be matched at this time is the | S | of the original point. Then the enumeration selects a target point from S to match it and records the minimum cost.

There is an intuitive approach to the cost of each step:

If the original point and the target point are in the same place, the cost is 0. Otherwise, if it is in the same column or slant, the cost is 1. Otherwise, the cost is 2.

This intuitive approach, however, is likely to be subconsciously rejected when it comes to it, as there may be ready or unplanned pieces blocking the way.

But in fact, it's right. (If you don't do this, you can't do it.) http://blog.csdn.net/xiefubao/article/details/25276999

(So... still have to dare to guess, violent shooting.... Feel that some of these guesses, put forward a seemingly correct proof, may have missed something... So even if you come up with a proof, you may not dare to guess.)

(There's no way to shoot with violence at all... so you still have to trust your own proof?)

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<algorithm>
 4 using namespace std;
 5 int pre_ans[100][9],num_pre;
 6 bool vis[9],vis2[100],vis3[100];
 7 int t1[9],t2[9],len;
 8 int T,TT,now,anss,cnt;
 9 int ans[300];
10 void pre_dfs(int x)
11 {
12     if(x>8)
13     {
14         ++num_pre;
15         memcpy(pre_ans[num_pre],t1,sizeof(t1));
16         return;
17     }
18     int i;
19     for(i=1;i<=8;i++)
20         if(!vis[i]&&!vis2[x-i+50]&&!vis3[x+i])
21         {
22             vis[i]=1;
23             vis2[x-i+50]=1;
24             vis3[x+i]=1;
25             t1[x]=i;
26             pre_dfs(x+1);
27             vis[i]=0;
28             vis2[x-i+50]=0;
29             vis3[x+i]=0;
30         }
31 }
32 int get_dis(int a,int b)
33 {
34     if(a==t1[b]&&pre_ans[now][a]==t2[b])    return 0;
35     if(a==t1[b])    return 1;
36     if(pre_ans[now][a]==t2[b])    return 1;
37     if(a+pre_ans[now][a]==t1[b]+t2[b])    return 1;
38     if(a-pre_ans[now][a]==t1[b]-t2[b])    return 1;
39     return 2; 
40 }
41 int main()
42 {
43     int i,j;
44     char c;
45     pre_dfs(1);
46     scanf("%d",&T);
47     for(TT=1;TT<=T;TT++)
48     {
49         len=0;anss=0x3f3f3f3f;
50         for(i=1;i<=8;i++)
51             for(j=1;j<=8;j++)
52             {
53                 c=getchar();
54                 while(c!='.'&&c!='q')    c=getchar();
55                 if(c=='q')
56                 {
57                     ++len;
58                     t1[len]=i;
59                     t2[len]=j;
60                 }
61             }
62         for(now=1;now<=num_pre;now++)
63         {
64             memset(ans,0x3f,sizeof(ans));
65             ans[0]=0;
66             for(i=1;i<(1<<8);i++)
67             {
68                 cnt=__builtin_popcount(i);
69                 for(j=1;j<=8;j++)
70                     if(i&(1<<(j-1)))
71                         ans[i]=min(ans[i],ans[i^(1<<(j-1))]+get_dis(j,cnt));
72             }
73             anss=min(anss,ans[(1<<8)-1]);
74         }
75         printf("Case %d: %d\n",TT,anss);
76     }
77 }

Posted by mcog_esteban on Fri, 08 Feb 2019 22:12:17 -0800