{purple7}

上午终于考完最后一科了

接下来就要开始刷题了

前几天先快速的把之前基础的东西再巩固一下,一两个月没碰很多东西又忘了

而且,很多东西回顾起来,理解的也更深一些

【回溯】

【搜索】

n皇后问题

 1 #include <cstdio>
 2 #include <iostream>
 3 #include <cstring>
 4 using namespace std;
 5 
 6 int vis[3][100];
 7 int n,tot;
 8 void dfs(int cur)
 9 {
10     if(cur==n) tot++;
11     else for(int i=0;i<n;i++) if(!vis[0][i]&& !vis[1][i+cur]&& !vis[2][i-cur+n])
12     {
13         vis[0][i]=vis[1][i+cur]=vis[2][i-cur+n]=1;
14         dfs(cur+1);
15         vis[0][i]=vis[1][i+cur]=vis[2][i-cur+n]=0;
16     }
17 
18 }
19 int main()
20 {
21     while(scanf("%d",&n)&&n)
22     {
23         memset(vis,0,sizeof(vis));
24         tot=0;
25         dfs(0);
26         printf("%d
",tot);
27     }
28 }
View Code

素数环UVA - 524 

 1 #include <cstdio>
 2 #include <iostream>
 3 #include <cstring>
 4 using namespace std;
 5 const int maxn=100;
 6 
 7 int a[20];
 8 int pri[maxn];
 9 int n;
10 int vis[20];
11 void init()
12 {
13     memset(pri,0,sizeof(pri));
14     for(int i=2;i*i<maxn;i++) if(!pri[i])
15     {
16         for(int j=i*i;j<maxn;j+=i) pri[j]=1;
17     }
18 }
19 void dfs(int cur)
20 {
21     if(cur==n&&!pri[a[n-1]+a[0]]){
22         for(int i=0;i<n-1;i++) printf("%d ",a[i]);
23         printf("%d
",a[n-1]);
24     }
25     else for(int i=1;i<=n;i++){
26         if(!vis[i]&&!pri[i+a[cur-1]])  a[cur]=i;
27         else continue;
28         vis[i]=1;
29         dfs(cur+1);
30         vis[i]=0;
31         }
32 }
33 int main()
34 {
35     int t=0;
36     int kase=1;
37     init();
38     a[0]=1;   //设定首位为1,否则会循环输出
39     vis[1]=1;
40     while(scanf("%d",&n)!=EOF)
41     {
42         if(t) puts("");
43         else t=1;
44         printf("Case %d:
",kase++);
45         dfs(1);  //从第二位开始
46     }
47 }
View Code

UVA - 129

 1 #include <iostream>
 2 #include <cstdio>
 3 using namespace std;
 4 
 5 const int MAXN = 80;
 6 
 7 int n, l, count;
 8 char v[MAXN+1];
 9 
10 // 判定是否有相邻的重复子串:只需要考虑追加1个字符后是否产生相邻重复子串
11 bool check(int curr)
12 {
13     for(int i=1; i<=(curr + 1) / 2; i++) {
14         bool equal = true;
15         for(int j=0; j<i; j++)
16             if(v[curr - i - j] != v[curr - j]) {
17                 equal = false;
18                 break;
19             }
20         if(equal)
21             return false;
22     }
23 
24     return true;
25 }
26 
27 void output_result(int curr)
28 {
29     for(int i=0; i<=curr; i++) {
30         if(i % 4 == 0 && i > 0) {
31             if(i % 64 == 0 && i > 0)
32                 puts("");
33             else
34                 putchar(' ');
35         }
36         putchar(v[i]);
37     }
38     printf("
%d
", curr+1);
39 }
40 
41 // 对于第curr字符,从‘A’到第l个字母都试探一遍
42 int dfs(int curr)
43 {
44     for(int i=0; i<l; i++) {
45         v[curr] = 'A' + i;
46         if(check(curr)) {
47             if(++count == n) {
48                 v[curr + 1] = '';
49                 output_result(curr);
50                 return 1;
51             } else if(dfs(curr + 1))
52                 return 1;
53         }
54     }
55 
56     return 0;
57 }
58 
59 int main()
60 {
61     while(cin >> n >> l) {
62         if(n == 0 && l == 0)
63             break;
64 
65         count = 0;
66         dfs(0);
67     }
68 
69     return 0;
70 }
COPY

UVA - 140 

带宽

剪枝不够彻底,,下次再回来做。

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<vector>
 4 #include<string>
 5 #include<algorithm>
 6 using namespace std;
 7 const int maxn=10;
 8 int id[256], letter[maxn];
 9 int n;
10 
11 void map_id_letter(char *p) 
12 {
13     n=0;
14     for(int c='A'; c<='Z'; c++) if(strchr(p, c)) 
15     {
16         id[c]=n;
17         letter[n]=c;
18         n++;
19     }
20 }
21 
22 int vis[maxn];
23 int ans;
24 int P[maxn], bestP[maxn], pos[maxn];
25 int edge[27][27];
26 
27 //生成排列
28 void gen(int d, int bw)
29 {
30     if(d==n)
31     {
32         ans=bw;
33         memcpy(bestP, P, sizeof(P));
34         return;
35     }
36 
37     for(int i=0;i<n;i++)
38     {
39         if(!vis[i])
40         {
41             vis[i]=1;
42             P[d]=i;
43             //如果新加的节点带宽大于现有带宽,剪枝
44             int w=0;//新加节点带宽
45             for(int j=0;j<d;j++)
46             {
47                 if(edge[i][P[j]])
48                 {
49                     w=d-j;            
50                     break;
51                 }
52             }
53             int cur_bw=max(bw, w);
54             if(cur_bw<ans)
55                 gen(d+1, cur_bw);
56             vis[i]=0;
57         }
58     }
59 }
60 
61 int main()
62 {
63 #ifndef ONLINE_JUDGE
64     freopen("./uva140.in", "r", stdin);
65 #endif
66     char buff[256];
67     while(gets(buff) && buff[0]!='#')
68     {
69         map_id_letter(buff);
70         char*p=strtok(buff, ";");
71         memset(edge, 0, sizeof(edge));
72         while(p)
73         {
74             int t=p[0];
75             ++p;//跳过:
76             while(*(++p))
77             {
78                 edge[id[t]][id[*p]]=1;
79                 edge[id[*p]][id[t]]=1;
80             }
81             p=strtok(0, ";");
82         }
83 
84         ans=n;
85         gen(0, 0);
86 
87         for(int i=0;i<n;i++)
88         {
89             printf("%c ", letter[bestP[i]]);
90         }
91         printf("-> %d
", ans);
92     }
93     
94     return 0;
95 }
CO

 POJ - 1077

八数码问题p199

题解:链接

直接bfs或者双向bfs

双向广度优先算法相对于广度优先算法来说,由于采用了从两个跟开始扩展的方式,搜索树的深度得到了明显的减少,所以在算法的时间复杂度和空间复杂度上都有较大的优势!双向广度优先算法特别适合于给出了起始节点和目的节点,要求他们之间的最短路径的问题。另外需要说明的是,广度优先的顺序能够保证找到的路径就是最短路径!

UVA - 10603

倒水

UVA - 1601

万圣节

 1 #include<cstdio>
 2 #include<algorithm>
 3 #include<cstring>
 4 #include<iostream>
 5 #include<queue>
 6 using namespace std;
 7 const int maxn=150,maxs=20;
 8 const int dx[]={-1,1,0,0,0};
 9 const int dy[]={0,0,1,-1,0};
10 inline int ID(int a,int b,int c)
11 {
12     return (a<<16)|(b<<8)|c;
13 }
14 int s[3],t[3]; //保存初末状态
15 int deg[maxn];//某个格子有多少个相连的格子
16 int G[maxn][5];//保存某个格子可以用到哪些格子
17 inline bool conflict(int a,int b,int a2,int b2)
18 {
19     return a2==b2||(a2==b&&b2==a); //如果两个鬼移动到同一个位置或者位置互换则冲突
20 }
21 int d[maxn][maxn][maxn]; //走到某个状态经过的步数
22 int bfs()
23 {
24     queue<int> q;
25     memset(d,-1,sizeof(d));
26     q.push(ID(s[0],s[1],s[2])); //每个状态给他编号来判断是否访问过
27     d[s[0]][s[1]][s[2]]=0;
28     while(!q.empty()){
29         int u=q.front();q.pop();
30         int a=(u>>16)&0xff,b=(u>>8)&0xff,c=u&0xff;  //0xff==1<<8;
31      //   cout<<a<<"   "<<b<<"    "<<c<<endl;
32         if(a==t[0]&&b==t[1]&&c==t[2])return d[a][b][c];
33         for(int i=0;i<deg[a];i++){
34             int a2=G[a][i];
35             for(int j=0;j<deg[b];j++){
36                 int b2=G[b][j];
37                 if(conflict(a,b,a2,b2))continue;
38                 for(int k=0;k<deg[c];k++){
39                     int c2=G[c][k];
40                     if(conflict(a,c,a2,c2))continue;
41                     if(conflict(b,c,b2,c2))continue;
42                     if(d[a2][b2][c2]!=-1)continue;
43                     d[a2][b2][c2]=d[a][b][c]+1;
44                     q.push(ID(a2,b2,c2));
45                 }
46             }
47         }
48     }
49     return -1;
50 }
51 int main()
52 {
53     int w,h,n;
54     //freopen("f.txt","r",stdin);
55     while(scanf("%d%d%d
",&w,&h,&n)==3&&n){
56         char maze[20][20];
57         for(int i=0;i<h;i++)
58             fgets(maze[i],20,stdin);
59         int cnt,x[maxn],y[maxn],id[maxn][maxn];
60         cnt=0;
61         for(int i=0;i<h;i++){
62             for(int j=0;j<w;j++){
63                 if(maze[i][j]!='#'){  //把障碍去掉,建图
64                     x[cnt]=i,y[cnt]=j,id[i][j]=cnt;
65                     if(islower(maze[i][j]))s[maze[i][j]-'a']=cnt;
66                     else if(isupper(maze[i][j]))t[maze[i][j]-'A']=cnt;
67                     cnt++;
68                 }
69             }
70         }
71         for(int i=0;i<cnt;i++){
72             deg[i]=0;
73             for(int dir=0;dir<5;dir++){
74                 int nx=x[i]+dx[dir],ny=y[i]+dy[dir];
75                 if(maze[nx][ny]!='#')G[i][deg[i]++]=id[nx][ny];//统计出每个位置可以移动到的位置
76             }
77         }
78      //n==1||n==2时,把格子加上,凑够三个,初末位置重合
79         if(n<=2){
80             deg[cnt]=1;G[cnt][0]=cnt;s[2]=t[2]=cnt++;
81         }
82         if(n<=1){
83             deg[cnt]=1;G[cnt][0]=cnt;s[1]=t[1]=cnt++;
84         }
85         printf("%d
",bfs());
86 
87     }
88 }
COPY

UVA - 11212

编辑书稿

【迭代加深搜索】 3d+h() >3maxd时剪枝。 其中h()为后继不正确的数字个数。原文链接

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstdlib>
 4 #include <cstring>
 5 #include <algorithm>
 6 using namespace std;
 7 int n, a[10], limit;
 8 
 9 bool is_sorted()
10 {
11     for(int i=0; i<n; i++)
12         if(a[i]!=i+1)return false;
13     return true;
14 }
15 
16 int h()
17 {
18     int cnt=0;
19     for(int i=0; i<n-1; i++)
20         if(a[i]+1!=a[i+1])
21             ++cnt;
22     return cnt;
23 }
24 
25 int dfs(int d)
26 {
27     if(d>limit)return 0;
28     if(d==limit && is_sorted())
29         return 1;
30     if(3*d+h()>limit*3)return 0;
31     int tmp[10];
32     memcpy(tmp, a, sizeof(a));
33     for(int i=1; i<n; i++)
34         for(int j=0; j+i-1<n; j++)
35         {
36             int t1[10], t2[10], c1=0, c2=0;
37             for(int k=0; k<n; k++)
38             {
39                 if(k>=j && k<=j+i-1)
40                     t1[c1++]=tmp[k];
41                 else t2[c2++]=tmp[k];
42             }
43             for(int k=0; k<j; k++)
44             {
45                 int c=0;
46                 for(int l=0; l<k; l++)
47                     a[c++]=t2[l];
48                 for(int l=0; l<c1; l++)
49                     a[c++]=t1[l];
50                 for(int l=k; l<c2; l++)
51                     a[c++]=t2[l];
52                 if(dfs(d+1))
53                     return 1;
54             }
55         }
56     return 0;
57 }
58 
59 int main()
60 {
61     int kase=0;
62     while(~scanf("%d", &n) && n)
63     {
64         int x[10];
65         for(int i=0; i<n; i++)
66             scanf("%d", &x[i]);
67         printf("Case %d: ", ++kase);
68         for(int i=0; ; i++)
69         {
70             limit=i;
71             memcpy(a, x, sizeof(a));
72             if(dfs(0))
73                 break;
74         }
75         printf("%d
", limit);
76     }
77     return 0;
78 }
COPY

UVA - 1343

【迭代加深搜索】 

题解1     题解2

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <algorithm>
 4 using namespace std;
 5 const int MAXN = 24, LEN = 8;
 6 int board[LEN][LEN - 1] = { {0, 2, 6, 11, 15, 20, 22}, {1, 3, 8, 12, 17, 21, 23},
 7                         {10, 9, 8, 7, 6, 5, 4}, {19, 18, 17, 16, 15, 14, 13},
 8                         {23, 21, 17, 12, 8, 3, 1}, {22, 20, 15, 11, 6, 2, 0},
 9                         {13, 14, 15, 16, 17, 18, 19}, {4, 5, 6, 7, 8, 9, 10} };
10 int check_order[] = {6, 7, 8, 11, 12, 15, 16, 17}, a[MAXN], maxd;
11 char order[30];
12 
13 int unordered() {
14     int n1 = 0, n2 = 0, n3 = 0;
15     for (int i = 0; i < LEN; i++) 
16         if (a[check_order[i]] == 1)  n1++;
17         else if (a[check_order[i]] == 2) n2++;
18         else n3++;
19     return LEN - max(max(n1, n2), n3);
20 }
21 
22 void rotate(int di) {
23     int t = a[board[di][0]];
24     for (int i = 1; i < LEN - 1; i++) a[board[di][i - 1]] = a[board[di][i]];
25     a[board[di][LEN - 2]] = t;
26 }
27 
28 bool dfs(int d) {
29     int cnt = unordered();
30     if (!cnt) return true;
31     if (cnt + d > maxd) return false;
32     int temp[MAXN]; memcpy(temp, a, sizeof(a));
33     for (int i = 0; i < LEN; i++) {
34         rotate(i);
35         order[d] = i + 'A';
36         if (dfs(d + 1)) return true;
37         memcpy(a, temp, sizeof(a));
38     }
39     return false;
40 }
41 
42 int main() {
43     freopen("in", "r", stdin);
44     while (scanf("%d", &a[0]) && a[0]) {
45         for (int i = 1; i < MAXN; i++) scanf("%d", &a[i]);
46         if (!unordered()) { printf("No moves needed
%d
", a[6]); continue;}
47         for (maxd = 1;; maxd++) if (dfs(0)) break;
48         for (int i = 0; i < maxd; i++) printf("%c", order[i]);
49         printf("
%d
", a[6]);
50     }
51     return 0;
52 }
1
  1 #define _CRT_SECURE_NO_WARNINGS 
  2 #include<iostream>
  3 #include<algorithm>
  4 #include<string>
  5 #include<sstream>
  6 #include<set>
  7 #include<vector>
  8 #include<stack>
  9 #include<map>
 10 #include<queue>
 11 #include<deque>
 12 #include<cstdlib>
 13 #include<cstdio>
 14 #include<cstring>
 15 #include<cmath>
 16 #include<ctime>
 17 #include<functional>
 18 using namespace std;
 19 
 20 int maxd, ok;
 21 int a[50];
 22 char ans[1000];
 23 int line[8][7] = {
 24     { 0, 2, 6, 11, 15, 20, 22 }, // A
 25     { 1, 3, 8, 12, 17, 21, 23 }, // B
 26     { 10, 9, 8, 7, 6, 5, 4 }, // C
 27     { 19, 18, 17, 16, 15, 14, 13 }, // D
 28 };
 29 const int rev[8] = { 5, 4, 7, 6, 1, 0, 3, 2 };//通过A,B,C,D,反推其他方向。指向反向,用来还原现场。
 30 const int final[8] = { 6, 7, 8, 11, 12, 15, 16, 17 };//最后答案要求的点
 31 bool is_final()
 32 {
 33     for (int i = 1; i < 8; i++)
 34     if (a[final[i]] != a[final[0]])
 35         return false;
 36     return true;
 37 }//终态
 38 int diff(int k)
 39 {
 40     int ans = 0;
 41     for (int i = 0; i < 8; i++)
 42     if (a[final[i]] != k)
 43         ans++;
 44     return ans;
 45 }
 46 int h() {//估值函数
 47     return min(min(diff(1), diff(2)), diff(3));
 48 }
 49 void move(int k)//按照方向移动
 50 {
 51     int tmp = a[line[k][0]];
 52     for (int i = 0; i < 6; i++)
 53         a[line[k][i]] = a[line[k][i + 1]];
 54     a[line[k][6]] = tmp;
 55 }
 56 void dfs(int cur)
 57 {
 58     if (is_final())
 59     {
 60         ans[cur] = '';
 61         printf("%s
", ans);
 62         ok = 1;
 63         return;
 64     }
 65     if (cur + h() > maxd) return;//剪枝
 66     for (int i = 0; i < 8; i++)
 67     {
 68         ans[cur] = 'A' + i;
 69         move(i);
 70         dfs(cur + 1);
 71         if (ok) return;
 72         move(rev[i]);//还原现场
 73     }
 74 }
 75 void init()//反推方向
 76 {
 77     for (int i = 4; i < 8; i++)
 78     for (int j = 0; j < 7; j++)
 79         line[i][j] = line[rev[i]][6 - j];
 80 }
 81 int main()
 82 {
 83     //freopen("t.txt", "r", stdin);
 84     init();
 85     while (scanf("%d", &a[0]) == 1 && a[0])
 86     {
 87         for (int i = 1; i < 24; i++) scanf("%d", &a[i]);
 88         for (int i = 0; i < 24; i++)
 89         if (!a[i])     return 0;
 90         ok = 0;
 91         if (is_final())
 92             printf("No moves needed
");
 93         else
 94         for (maxd = 1;; maxd++)
 95         {
 96             dfs(0);
 97             if (ok)   break;
 98         }
 99         printf("%d
", a[6]);//最终的颜色
100     }
101     return 0;
102 }
!2

UVA - 1374

【迭代加深搜索】 

 1 #include <cstdio>
 2 int n, MAX, A[35];
 3 
 4 bool DFS(int cur, int now){
 5     if (cur > MAX || now <= 0 || now << (MAX - cur) < n)
 6         return false;
 7     if (now == n || now << (MAX - cur) == n)
 8         return true;
 9 
10     A[cur] = now;
11     for (int i = 0; i <= cur; ++i) {
12         if (DFS(cur + 1, now + A[i]))
13             return true;
14         if (DFS(cur + 1, now - A[i]))
15             return true;
16     }
17 
18     return false;
19 }
20 
21 int main() {
22     while (scanf("%d", &n), n) {
23         for (MAX = 0; !DFS(0, 1); ++MAX);
24         printf("%d
", MAX);
25     }
26     return 0;
27 }
COPY


IDA*基本理解得差不多了。。。

uva12325

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <iostream>
 4 using namespace std;
 5 
 6 int main()
 7 {
 8     int t;
 9     int n,s1,v1,s2,v2;
10     scanf("%d",&t);
11     while(t--)
12     {
13         int best=0;
14         scanf("%d%d%d%d%d",&n,&s1,&v1,&s2,&v2);
15         int a=s2*v1;
16         int b=s1*v2;
17         if(a<b)
18         {
19             for(int i=0;i<s2&&i*s1<=n;i++)
20             {
21                 int temp=v1*i+(n-s1*i)/s2*v2;
22                 best=max(best,temp);
23             }
24         }
25         else
26         {
27             for(int i=0;i<s1&&i*s2<=n;i++)
28             {
29                 int temp=i*v2+(n-i*s2)/s1*v1;
30                 best=best>temp?best:temp;
31             }
32 
33         }
34         printf("%d
",best);
35     }
36 }
View Code

 上面错了。。。

 1 #include<cstdio>
 2 #include<iostream>
 3 #include<algorithm>
 4 using namespace std;
 5 int main()
 6 {
 7     int t,n,s1,v1,s2,v2;
 8     scanf("%d",&t);
 9     for(int tt=1; tt<=t; tt++)
10     {
11         //输入体积为n的箱子,和宝物1的体积、价值以及宝物2的体积、价值。
12         scanf("%d%d%d%d%d",&n,&s1,&v1,&s2,&v2);
13         //性价比=价/量
14         if(s1>s2)
15         {
16             swap(s1,s2);
17             swap(v1,v2);
18         }
19         printf("Case #%d: ",tt);
20         //此时s2肯定是比s1大的,但若如此n/s2都大于65536的话,说明
21         //不管是枚举宝物1还是宝物2的时间复杂度都是很大的!
22         long long value=0;
23         if(n/s2>=65536)// 当n/s1和n/s2都非常大的时候
24         {
25 
26             for(long long i=0; i<=s1; i++)
27                 value=max(value,v2*i+(n-i*s2)/s1*v1);
28             for(long long i=0; i<=s2; i++)
29                 value=max(value,v1*i+(n-i*s1)/s2*v2);
30         }
31         else//因为数据交换的原因,s2要大些,所以n/s2要小些,此时枚举宝物2的个数
32         {
33             for(long long i=0; s2*i<=n; i++)
34             value=max(value,v2*i+(n-s2*i)/s1*v1);
35         }
36         printf("%lld
",value);
37     }
38     return 0;
39 }
COPY

待解决UVA - 1602

题解:链接

UVA - 208

dfs

要事先判断节点1是否可以到达节点k,否则会超时。

 1 #include <bits/stdc++.h>
 2 #include <cstdio>
 3 using namespace std;
 4 const int maxn=22;
 5 int x;
 6 int u,v;
 7 int g[maxn][maxn];
 8 int tempg[maxn][maxn];
 9 int is[maxn],vis[maxn];
10 int cnt=0;
11 int p[maxn];
12 
13 void dfs(int id)
14 {
15     if(!tempg[1][x]) return ;
16     if(id>maxn) return;
17     if(p[id-1]==x)
18     {
19         cnt++;
20         printf("1");
21         for(int i=1;i<id;i++) printf(" %d",p[i]);
22         puts("");
23         return ;
24     }
25     for(int i=2;i<maxn;i++) if(is[i]&&g[p[id-1]][i]&&!vis[i]&&tempg[i][x])
26     {
27         p[id]=i;
28         vis[i]=1;
29         dfs(id+1);
30         vis[i]=0;
31     }
32 }
33 bool floyd(int y)
34 {
35     memcpy(tempg,g,sizeof(g));
36     for(int k=1;k<maxn;k++)
37         for(int i=1;i<maxn;i++)
38             for(int j=1;j<maxn;j++)
39                     if(tempg[i][k]==1&&tempg[k][j]==1) tempg[i][j]=1;
40 
41     return tempg[1][y];
42 
43 
44 
45 }
46 int main()
47 {
48     int kase=0;
49     while(scanf("%d",&x)!=EOF)
50     {
51         cnt=0;
52         memset(vis,0,sizeof(vis));
53         memset(is,0,sizeof(is));
54         memset(g,0,sizeof(g));
55         memset(tempg,0,sizeof(tempg));
56         while(scanf("%d%d",&u,&v)&&(u||v)){
57             is[u]=is[v]=1;
58             g[u][v]=g[v][u]=1;
59         }
60         printf("CASE %d:
",++kase);
61         floyd(x);
62         p[0]=1;
63         dfs(1);
64         printf("There are %d routes from the firestation to streetcorner %d.
",cnt,x);
65     }
66 }
View Code

还是不会剪枝。。。

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<algorithm>
 4 using namespace std;
 5 const int MAX = 250;
 6 const int limit = 105;
 7 const int N = 50;
 8 int dir[4][2] = {{1,0},{0,1},{0,-1},{-1,0}};
 9 char face[4] = {'e','n','s','w'};
10 int step[N],ans,n,m;
11 int sum[25];
12 int g[MAX][MAX];
13 
14 bool judge(int x,int y, int d,int f) {
15     for(int i = 1; i <= d; i++) {
16         x += dir[f][0];
17         y += dir[f][1];
18         if(abs(x) > limit || abs(y) > limit)
19             return true;
20         if(g[x + limit][y + limit] == -1)
21             return true;
22     }
23     if(abs(x) + abs(y) > sum[n] - sum[d])
24         return true;
25     return false;
26 }
27 void dfs(int x, int y, int d, int f) {
28     if(d > n) {
29         if(x == 0 && y == 0) {
30             for(int i = 1; i <=n; i++) {
31                 printf("%c",face[step[i]]);
32             }
33             printf("
");
34             ans++;
35         }    
36         return;
37     }
38     for(int i = 0; i < 4; i++) {
39         if(i == f || i + f == 3)
40             continue;
41         int xx = x + dir[i][0] * d;
42         int yy = y + dir[i][1] * d;
43         if(judge(x,y,d,i))
44             continue;
45         if(g[xx + limit][yy + limit])
46             continue;
47         g[xx + limit][yy + limit] = 1;
48         step[d] = i;
49         dfs(xx,yy,d + 1,i);
50         g[xx + limit][yy + limit] = 0;
51     }
52 }
53 
54 int main() {
55     sum[0] = 0;
56     for(int i = 1; i <= 20; i++) {
57         sum[i] = i + sum[i - 1];
58     }
59     int t;
60     scanf("%d",&t);
61     while(t--) {
62         scanf("%d%d",&n,&m);
63         memset(g, 0, sizeof(g));
64         ans = 0;
65         int a,b;
66         for(int i = 0; i < m; i++) {
67             scanf("%d%d",&a,&b);
68             if(abs(a) > limit || abs(b) > limit)
69                 continue;
70             g[a + limit][b + limit] = -1;
71         }
72         dfs(0,0,1,-1);
73         printf("Found %d golygon(s).

",ans);
74     }
75 }
COPY
原文地址:https://www.cnblogs.com/yijiull/p/7150524.html