Input
每组数据的第一行是两个正整数,n k,用一个空格隔开,表示了将在一个n*n的矩阵内描述棋盘,以及摆放棋子的数目。 n <= 8 , k <= n
当为-1 -1时表示输入结束。
随后的n行描述了棋盘的形状:每行有n个字符,其中 # 表示棋盘区域, . 表示空白区域(数据保证不出现多余的空白行或者空白列)。
Output
Sample Input
2 1 #. .# 4 4 ...# ..#. .#.. #... -1 -1
Sample Output
2 1
#include<iostream> #include<algorithm> #include<cstring> using namespace std; char map[20][20]; int vis[20]; int sum,cnt,n,k; void dfs(int s) { if(cnt==k) { sum++; return ; } else { if(s>=n)//出界 { return ; } for(int i=0;i<n;i++) { if(!vis[i]&&map[s][i]=='#') { vis[i]=1; cnt++; dfs(s+1); cnt--;//回溯一次就要建一个棋子。 vis[i]=0; //和上面那一步理解一样 } } dfs(s+1);//继续下下一种方案,直到全部扫描完 } } int main() { while(cin>>n>>k) { if(n==-1&&k==-1) break; memset(map,0,sizeof(map)); memset(vis,0,sizeof(vis)); for(int i=0;i<n;i++) for(int j=0;j<n;j++) { cin>>map[i][j]; } cnt=0;sum=0; dfs(0); cout<<sum<<endl; } return 0; }
你的任务是,对于给定的N,求出有多少种合法的放置方法。
#include <cstdio> #include <cmath> int qizi[20];//qizi【i】=j表示 第i行第j列下有棋 int biao[11];//结果存到表中,不存会超时 int n; int qingkuang; bool judge(int hang) { for(int i=1;i<hang;i++)//扫之前下过棋每一行是否有与此次所下棋的位置同列的 或同对角线的 { if(qizi[i]==qizi[hang]||abs(hang-i)==abs(qizi[hang]-qizi[i]))//对角线的话斜率的绝对值=1 return false; } return true; } void dfs(int hang) { if(hang==n+1)//比如n=2,然后该第二行下棋了,第二行如果能成功选择的话,那么那么新的行数3就等于n+1=3了 ,实在不懂举个例子看看 qingkuang++; else { for(int j=1;j<=n;j++)//在该行选第几列 { qizi[hang]=j; if(judge(hang)) { dfs(hang+1);//在本行能下棋的话,就接着下下一行的棋 } } } } void cnt(int n) { dfs(1);//从第一行开始选地方下棋 } int main() { for(n=1;n<=10;n++) { qingkuang=0; cnt(n); biao[n]=qingkuang; } int q; while(scanf("%d",&q)!=EOF) { if(q==0) break; printf("%d ",biao[q]); } return 0; }
Time Limit: 1000MS | Memory Limit: 65536K | |
Total Submissions: 46573 | Accepted: 17552 |
Description
Is an escape possible? If yes, how long will it take?
Input
L is the number of levels making up the dungeon.
R and C are the number of rows and columns making up the plan of each level.
Then there will follow L blocks of R lines each containing C characters. Each character describes one cell of the dungeon. A cell full of rock is indicated by a '#' and empty cells are represented by a '.'. Your starting position is indicated by 'S' and the exit by the letter 'E'. There's a single blank line after each level. Input is terminated by three zeroes for L, R and C.
Output
Escaped in x minute(s).
where x is replaced by the shortest time it takes to escape.
If it is not possible to escape, print the line
Trapped!
Sample Input
3 4 5 S.... .###. .##.. ###.# ##### ##### ##.## ##... ##### ##### #.### ####E 1 3 3 S## #E# ### 0 0 0
Sample Output
Escaped in 11 minute(s). Trapped!
一个3维的bfs模板题
#include <iostream> #include <string> #include <cstring> #include <queue> using namespace std; struct Node{ int x,y,z; int cont; }; char Map[35][35][35]; int visit[35][35][35]; int dir[6][3] = {{0,0,1},{0,0,-1},{0,1,0},{0,-1,0},{1,0,0},{-1,0,0}}; int l,r,c; int x1,y1,z1; void bfs(){ queue <Node> Q; Node t; t.x = x1,t.y = y1,t.z = z1,t.cont = 0; visit[x1][y1][z1] = 1; Q.push(t); while(!Q.empty()){ Node res = Q.front(); Q.pop(); int xx = res.x; int yy = res.y; int zz = res.z; int Cont = res.cont; if(Map[xx][yy][zz] == 'E'){ //目标位置且一定最短 cout<<"Escaped in "<<Cont<<" minute(s)."<<endl; return ; } for(int i = 0;i < 6;i ++){ //每一步6个状态 Node temp; int xi = temp.x = xx+dir[i][0]; int yi = temp.y = yy+dir[i][1]; int zi = temp.z = zz+dir[i][2]; temp.cont = Cont+1; if(xi < 1 || xi > l || yi < 1 || yi > r || zi < 1 || zi > c) continue; //边界判断 if(Map[xi][yi][zi] != '#' && !visit[xi][yi][zi]){ visit[xi][yi][zi] = 1; Q.push(temp); } } } cout<<"Trapped!"<<endl; } int main() { while(cin>>l>>r>>c){ if(l == 0 && r == 0 && c == 0) break; for(int i = 1;i <= l;i ++){ for(int j = 1;j <= r;j ++){ for(int k = 1;k <= c;k ++){ cin>>Map[i][j][k]; if(Map[i][j][k] == 'S') x1 = i,y1 = j,z1 = k; } } } memset(visit,0,sizeof(visit)); bfs(); } return 0; }
Farmer John has been informed of the location of a fugitive cow and wants to catch her immediately. He starts at a point N (0 ≤ N ≤ 100,000) on a number line and the cow is at a point K (0 ≤ K ≤ 100,000) on the same number line. Farmer John has two modes of transportation: walking and teleporting.
* Walking: FJ can move from any point X to the points X - 1 or X + 1 in a single minute
* Teleporting: FJ can move from any point X to the point 2 × X in a single minute.
If the cow, unaware of its pursuit, does not move at all, how long does it take for Farmer John to retrieve it?
Input
Output
Sample Input
5 17
Sample Output
4
基础BFS的题目
#include<iostream> #include<algorithm> #include<queue> #include<cstring> using namespace std; struct point{ int x,y,step; }st; int n,m; queue<point>q; int vst[200000]; int flag; int bfs() { while(!q.empty()) { q.pop(); } memset(vst,0,sizeof(vst)); vst[st.x]=1;//标明起始位置; q.push(st); while(!q.empty()) { point now=q.front(); if(now.x==m) { return now.step;//返回当前花费的时间。 } q.pop(); for(int j=0;j<3;j++)//每个结点遍历3种情况; { point next=now; if(j==0) { next.x=now.x+1; } else if(j==1) { next.x=now.x-1; } else if(j==2) { next.x=now.x*2; } next.step++; if(next.x==m) { return next.step; } if(next.x>=0&&next.x<=200000&&!vst[next.x]) { vst[next.x]=1; q.push(next); } } } return 0; } int main() { while(cin>>n>>m) { st.x=n; st.step=0; cout<<bfs()<<endl; } return 0; }
Input
Output
Sample Input
2 6 19 0
Sample Output
10 100100100100100100 111111111111111111
第一种dfs写法。
#include<iostream> #include<algorithm> #define ll long long using namespace std; int n;int flag; void dfs(int x,ll y) { if(x>19||flag==1) { return; } if(y%n==0) { flag=1; cout<<y<<endl; return; } dfs(x+1,y*10); dfs(x+1,y*10+1); } int main() { while(cin>>n) { if(!n) { break; } flag=0; dfs(1,1); } return 0; }
第二种bfs写法。
# include <stdio.h> # include <queue> using namespace std; int m; void BFS(long long x) { queue<long long>Q; Q.push(x); while(Q.size()) { long long y = Q.front(); Q.pop(); if(y%m == 0) { printf("%lld ",y); return; } Q.push(y*10); Q.push(y*10+1); } } int main(void) { while(~scanf("%d",&m),m) { BFS(1); } return 0; }
— It is a matter of security to change such things every now and then, to keep the enemy in the dark.
— But look, I have chosen my number 1033 for good reasons. I am the Prime minister, you know!
— I know, so therefore your new number 8179 is also a prime. You will just have to paste four new digits over the four old ones on your office door.
— No, it’s not that simple. Suppose that I change the first digit to an 8, then the number will read 8033 which is not a prime!
— I see, being the prime minister you cannot stand having a non-prime number on your door even for a few seconds.
— Correct! So I must invent a scheme for going from 1033 to 8179 by a path of prime numbers where only one digit is changed from one prime to the next prime.
Now, the minister of finance, who had been eavesdropping, intervened.
— No unnecessary expenditure, please! I happen to know that the price of a digit is one pound.
— Hmm, in that case I need a computer program to minimize the cost. You don't know some very cheap software gurus, do you?
— In fact, I do. You see, there is this programming contest going on... Help the prime minister to find the cheapest prime path between any two given four-digit primes! The first digit must be nonzero, of course. Here is a solution in the case above.
1033The cost of this solution is 6 pounds. Note that the digit 1 which got pasted over in step 2 can not be reused in the last step – a new 1 must be purchased.
1733
3733
3739
3779
8779
8179
Input
Output
Sample Input
3 1033 8179 1373 8017 1033 1033
Sample Output
6 7 0
题目意思就是从第一个数变成第二个数所需的步骤数并且变化的每个过程中产生的数都必须要是素数。
#include #include #include #include #include using namespace std; mapg; bool flag[10000]; void star() { for(int i = 1000; i < 10000; i++) { for(int j = 2; j*j <= i; j++) if(i%j == 0) { g[i] = 1; break; } } } struct node { int x; int step; node(){} node(int xx, int ss) { x = xx; step = ss; } }; queueque; void bfs(int n, int m) { while(!que.empty()) que.pop(); que.push(node(n, 0)); int a[4]; memset(flag, 0, sizeof(flag)); while(!que.empty()) { node tmp = que.front(); que.pop(); int t = tmp.x; // printf("%d--%d ", t, tmp.step); for(int i = 0; i < 4; i++) { a[i] = t%10; t /= 10; } int temp = 1; for(int i = 0; i < 4; i++) { for(int j = 0; j < 10; j++) { if(i == 3 && j == 0) continue; if(j == a[i]) continue; int x = tmp.x - a[i]*temp + j*temp; if(x == m) {printf("%d ", tmp.step+1);return;} if(!g.count(x) && !flag[x]) { que.push(node(x, tmp.step+1)); flag[x] = 1; } } temp *= 10; } } } int main(void) { int T; star(); scanf("%d", &T); while(T--) { int n, m; scanf("%d%d", &n, &m); if(n == m) { printf("0 "); continue; } bfs(n, m); } return 0; }
POJ-3087
已知两堆牌s1和s2的初始状态, 其牌数均为c,按给定规则能将他们相互交叉组合成一堆牌s12,再将s12的最底下的c块牌归为s1,最顶的c块牌归为s2,依此循环下去。给定输入s1和s2的初始状态 以及 预想的最终状态s12。
#include <stdio.h> #include <map> #include <string.h> #include <string> using namespace std; int main() { int n,c,t=0,cut,i; scanf("%d",&n); while(n--) { scanf("%d",&c); t++; cut=0; char s1[110],s2[110],s12[220],s[220]; scanf("%s%s%s",s1,s2,s12); map <string,int > map1; int len,flat=0; while(1) { cut++; len=0; for(i=0;i<c;i++) { s[len]=s2[i]; len++; s[len]=s1[i]; len++; } s[len]='