{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\n",tot); 27 } 28 }
素数环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\n",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:\n",kase++); 45 dfs(1); //从第二位开始 46 } 47 }
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("\n%d\n", 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] = '\0'; 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 }
带宽
剪枝不够彻底,,下次再回来做。
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\n", ans); 92 } 93 94 return 0; 95 }
八数码问题p199
题解:链接
直接bfs或者双向bfs
双向广度优先算法相对于广度优先算法来说,由于采用了从两个跟开始扩展的方式,搜索树的深度得到了明显的减少,所以在算法的时间复杂度和空间复杂度上都有较大的优势!双向广度优先算法特别适合于给出了起始节点和目的节点,要求他们之间的最短路径的问题。另外需要说明的是,广度优先的顺序能够保证找到的路径就是最短路径!
倒水
万圣节
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\n",&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\n",bfs()); 86 87 } 88 }
编辑书稿
【迭代加深搜索】 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\n", limit); 76 } 77 return 0; 78 }
【迭代加深搜索】
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\n%d\n", 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("\n%d\n", a[6]); 50 } 51 return 0; 52 }
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] = '\0'; 61 printf("%s\n", 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\n"); 93 else 94 for (maxd = 1;; maxd++) 95 { 96 dfs(0); 97 if (ok) break; 98 } 99 printf("%d\n", a[6]);//最终的颜色 100 } 101 return 0; 102 }
【迭代加深搜索】
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\n", MAX); 25 } 26 return 0; 27 }
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\n",best); 35 } 36 }
上面错了。。。
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\n",value); 37 } 38 return 0; 39 }
待解决UVA - 1602
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:\n",++kase); 61 floyd(x); 62 p[0]=1; 63 dfs(1); 64 printf("There are %d routes from the firestation to streetcorner %d.\n",cnt,x); 65 } 66 }
还是不会剪枝。。。
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("\n"); 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).\n\n",ans); 74 } 75 }