一些杭电上的题目,给出代码,我具体理解的也不是很好。没有理解,就是不行啊,现在都有点忘了。
Tempter of the Bone
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 19092 Accepted Submission(s): 5331
Problem Description
The doggie found a bone in an ancient maze, which fascinated him a lot. However, when he picked it up, the maze began to shake, and the doggie could feel the ground sinking. He realized that the bone was a trap, and he tried desperately to get out of this maze.
The maze was a rectangle with sizes N by M. There was a door in the maze. At the beginning, the door was closed and it would open at the T-th second for a short period of time (less than 1 second). Therefore the doggie had to arrive at the door on exactly the T-th second. In every second, he could move one block to one of the upper, lower, left and right neighboring blocks. Once he entered a block, the ground of this block would start to sink and disappear in the next second. He could not stay at one block for more than one second, nor could he move into a visited block. Can the poor doggie survive? Please help him.
Input
The input consists of multiple test cases. The first line of each test case contains three integers N, M, and T (1 < N, M < 7; 0 < T < 50), which denote the sizes of the maze and the time at which the door will open, respectively. The next N lines give the maze layout, with each line containing M characters. A character is one of the following:
'X': a block of wall, which the doggie cannot enter;
'S': the start point of the doggie;
'D': the Door; or
'.': an empty block.
The input is terminated with three 0's. This test case is not to be processed.
Output
For each test case, print in one line "YES" if the doggie can survive, or "NO" otherwise.
Sample Input
4 4 5
S.X.
..X.
..XD
....
3 4 5
S.X.
..X.
...D
0 0 0
Sample Output
NO
YES
#include <iostream>
using namespace std;
#include <stdio.h>
#include <math.h>
#include <string.h>
#define N 10
int dir[4][2] = {0,-1,1,0,0,1,-1,0};//define up,right,down,left index
int escape,di,dj,T,m,n;//escape 是否逃脱,di,dj为目的地址坐标,T为恰好到达的时间,m,n为地图大小
char map[N][N];
void dfs(int si,int sj,int t)//t 记录现在已经走了几步
{
int i;
if(si == di && sj == dj && t == T)//成功到达目的地,并且时间相等,成功逃脱
{
escape = 1;
return;
}
if(si < 0 || si >= m || sj < 0 || sj >= n)//越界中断
return;
if(T-t <(abs(si-di)+abs(sj-dj)))//如果剩下要走的步 少于当前能够到达的最少步 则逃脱失败
return;
if(( T - t - abs(si - di) - abs(sj - dj) ) % 2 != 0)//奇偶剪枝 如果剩下要走的步 多于当前能够到达的最少步
//求差,如果不是为偶数,则无法准确到达,即逃脱失败
return;
for(i = 0 ; i < 4; i++)//各个方向搜索开始
{
if(si + dir[i][0] >= 0 && si + dir[i][0] < m && sj + dir[i][1] >= 0 && sj + dir[i][1] < n )
{//保证每个搜索的点,都在map中
if(map[si + dir[i][0]][sj+dir[i][1]] != 'X' )
{
map[si + dir[i][0]][sj+dir[i][1]] = 'X';//将访问过的标记已访问
dfs(si+dir[i][0],sj+dir[i][1],t+1);//从这一点开始,继续深度优先搜索
if(escape) return;//如果逃脱则返回
map[si+dir[i][0]][sj+dir[i][1]] = '.';//回溯,赋值初始值
}
}
}
return ;
}
int main()
{
int i,j,si,sj,t,num;
while(scanf("%d %d %d",&m,&n,&T) != EOF)
{
getchar();
if(m == 0 && n == 0 && T == 0)
break;
num = 0;
for(i = 0 ; i < m ; i++)
{
for(j = 0 ; j < n ; j++)
{
scanf("%c",&map[i][j]);
if(map[i][j] == 'S')
si = i,sj = j;
else if(map[i][j] == 'D')
di = i,dj = j;
else if(map[i][j] == 'X')
num++;
}
getchar();
}
if(m*n - num < T)//路径剪枝,如果能走的路小于时间T,则无法到达
{
puts("NO");
continue;
}
escape = 0;
map[si][sj] = 'X';
dfs(si,sj,0);
puts(escape ? "YES" : "NO" );
}
}
Oil Deposits
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 2474 Accepted Submission(s): 1390
Problem Description
The GeoSurvComp geologic survey company is responsible for detecting underground oil deposits. GeoSurvComp works with one large rectangular region of land at a time, and creates a grid that divides the land into numerous square plots. It then analyzes each plot separately, using sensing equipment to determine whether or not the plot contains oil. A plot containing oil is called a pocket. If two pockets are adjacent, then they are part of the same oil deposit. Oil deposits can be quite large and may contain numerous pockets. Your job is to determine how many different oil deposits are contained in a grid.
Input
The input file contains one or more grids. Each grid begins with a line containing m and n, the number of rows and columns in the grid, separated by a single space. If m = 0 it signals the end of the input; otherwise 1 <= m <= 100 and 1 <= n <= 100. Following this are m lines of n characters each (not counting the end-of-line characters). Each character corresponds to one plot, and is either `*', representing the absence of oil, or `@', representing an oil pocket.
Output
For each grid, output the number of distinct oil deposits. Two different pockets are part of the same oil deposit if they are adjacent horizontally, vertically, or diagonally. An oil deposit will not contain more than 100 pockets.
Sample Input
1 1
*
3 5
*@*@*
**@**
*@*@*
1 8
@@****@*
5 5
****@
*@@*@
*@**@
@@@*@
@@**@
0 0
Sample Output
0
1
2
2
#include <iostream>
using namespace std;
int dir[8][2] = {0,-1,1,-1,1,0,1,1,0,1,-1,1,-1,0,-1,-1};
char map[110][110];
int m,n;
void dfs(int a,int b)
{
int i;
for(i = 0 ; i < 8 ; i++)
{
if(a+dir[i][0] >= 0 && a+dir[i][0] < m && b+dir[i][1] >= 0 && b+dir[i][1] < n)
{
if(map[a+dir[i][0]][b+dir[i][1]] == '@')
{
map[a+dir[i][0]][b+dir[i][1]] = '*';
dfs(a+dir[i][0],b+dir[i][1]);
}
}
}
}
int main()
{
while(scanf("%d %d",&m,&n) != EOF)
{
int i,j;
int cnt = 0;
if(m == 0 || n == 0)
break;
for(i = 0 ; i < m;i++)
scanf("%s",map[i]);
for(i = 0 ; i < m;i++)
{
for(j = 0 ; j < n;j++)
{
if(map[i][j] == '@')
{
map[i][j] = '*';
dfs(i,j);
cnt++;
}
}
}
printf("%d\n",cnt);
}
}
Prime Ring Problem
Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 7023 Accepted Submission(s): 3144
Problem Description
A ring is compose of n circles as shown in diagram. Put natural number 1, 2, ..., n into each circle separately, and the sum of numbers in two adjacent circles should be a prime.
Note: the number of first circle should always be 1.
Input
n (0 < n < 20).
Output
The output format is shown as sample below. Each row represents a series of circle numbers in the ring beginning from 1 clockwisely and anticlockwisely. The order of numbers must satisfy the above requirements. Print solutions in lexicographical order.
You are to write a program that completes above process.
Print a blank line after each case.
Sample Input
6
8
Sample Output
Case 1:
1 4 3 2 5 6
1 6 5 2 3 4
Case 2:
1 2 3 8 5 6 7 4
1 2 5 8 3 4 7 6
1 4 7 6 5 8 3 2
1 6 7 4 3 8 5 2
#include <iostream>
using namespace std;
int prim[40];
int res[25];
int mark[25];
int n;
void dfs(int t)
{
if(t == n+1)
{
if(prim[1+res[t-1]])
{
printf("1");
int i;
for(i = 2; i <= n ;i++)
printf(" %d",res[i]);
printf("\n");
}
return;
}
int i;
for(i = 2; i <= n;i++)
{
if(!mark[i] && prim[res[t-1]+i])
{
mark[i] = 1;
res[t] = i;
dfs(t+1);
mark[i] = 0;
}
}
}
int main()
{
prim[3] = prim[5] = prim[7] = prim[11] = prim[13] = prim[17] = prim[19] = prim[23] = prim[29] = prim[31] = 1;
memset(mark,0,sizeof(mark));
int cnt = 0;
while(scanf("%d",&n) != EOF)
{
printf("Case %d:\n",++cnt);
mark[1] = 1;
res[1] = 1;
dfs(2);
printf("\n");
}
}
Zipper
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 2179 Accepted Submission(s): 779
Problem Description
Given three strings, you are to determine whether the third string can be formed by combining the characters in the first two strings. The first two strings can be mixed arbitrarily, but each must stay in its original order.
For example, consider forming "tcraete" from "cat" and "tree":
String A: cat
String B: tree
String C: tcraete
As you can see, we can form the third string by alternating characters from the two strings. As a second example, consider forming "catrtee" from "cat" and "tree":
String A: cat
String B: tree
String C: catrtee
Finally, notice that it is impossible to form "cttaree" from "cat" and "tree".
Input
The first line of input contains a single positive integer from 1 through 1000. It represents the number of data sets to follow. The processing for each data set is identical. The data sets appear on the following lines, one data set per line.
For each data set, the line of input consists of three strings, separated by a single space. All strings are composed of upper and lower case letters only. The length of the third string is always the sum of the lengths of the first two strings. The first two strings will have lengths between 1 and 200 characters, inclusive.
Output
For each data set, print:
Data set n: yes
if the third string can be formed from the first two, or
Data set n: no
if it cannot. Of course n should be replaced by the data set number. See the sample output below for an example.
Sample Input
3
cat tree tcraete
cat tree catrtee
cat tree cttaree
Sample Output
Data set 1: yes
Data set 2: yes
Data set 3: no
《此题还有DP的做法》
#include <iostream>
#include <string.h>
using namespace std;
int n;
int flag;
int len1,len2,len3;
int marka[205],markb[205];
char a[205],b[205],c[410];
void dfs(int i,int j, int k)
{
if(k == len3)
{
flag = 1;
return;
}
if(marka[i] && markb[j] )
return;
if(i < len1 && a[i] == c[k]) {marka[i] = 1;dfs(i+1,j,k+1);}
if(j < len2 && b[j] == c[k]) {markb[j] = 1;dfs(i,j+1,k+1);}
}
int main()
{
scanf("%d",&n);
int cnt = 0;
while(n--)
{
printf("Data set %d: ",++cnt);
int i;
scanf("%s %s %s",a,b,c);
len1 = strlen(a);
len2 = strlen(b);
len3 = strlen(c);
memset(marka,0,sizeof(marka));
memset(markb,0,sizeof(markb));
flag = 0;
dfs(0,0,0);
puts(flag ? "yes":"no");
}
}
变形课
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 131072/65536 K (Java/Others)
Total Submission(s): 3011 Accepted Submission(s): 1000
Problem Description
呃......变形课上Harry碰到了一点小麻烦,因为他并不像Hermione那样能够记住所有的咒语而随意的将一个棒球变成刺猬什么的,但是他发现了变形咒语的一个统一规律:如果咒语是以a开头b结尾的一个单词,那么它的作用就恰好是使A物体变成B物体.
Harry已经将他所会的所有咒语都列成了一个表,他想让你帮忙计算一下他是否能完成老师的作业,将一个B(ball)变成一个M(Mouse),你知道,如果他自己不能完成的话,他就只好向Hermione请教,并且被迫听一大堆好好学习的道理.
Input
测试数据有多组。每组有多行,每行一个单词,仅包括小写字母,是Harry所会的所有咒语.数字0表示一组输入结束.
Output
如果Harry可以完成他的作业,就输出"Yes.",否则就输出"No."(不要忽略了句号)
Sample Input
so
soon
river
goes
them
got
moon
begin
big
0
#include <iostream>
using namespace std;
typedef struct
{
char begin,end;
int flag;
}Model;
int n,flag;
Model test[10000];
void dfs(char c)
{
if(flag == 1)
return;
if(c == 'm')
{
flag = 1;
return;
}
int i;
for(i = 1; i < n;i++)
{
if(test[i].begin == c && test[i].flag == 0)
{
test[i].flag = 1;
dfs(test[i].end);
test[i].flag = 0;
}
}
}
int main()
{
char s[20];
while(scanf("%s",s) != EOF)
{
n = 1;
while(strcmp(s,"0"))
{
test[n].begin = s[0];
test[n].end = s[strlen(s)-1];
test[n].flag = 0;
n++;
scanf("%s",s);
}
flag = 0;
dfs('b');
puts(flag ?"Yes.":"No.");
}
}
Red and Black
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 1759 Accepted Submission(s): 1165
Problem Description
There is a rectangular room, covered with square tiles. Each tile is colored either red or black. A man is standing on a black tile. From a tile, he can move to one of four adjacent tiles. But he can't move on red tiles, he can move only on black tiles.
Write a program to count the number of black tiles which he can reach by repeating the moves described above.
Input
The input consists of multiple data sets. A data set starts with a line containing two positive integers W and H; W and H are the numbers of tiles in the x- and y- directions, respectively. W and H are not more than 20.
There are H more lines in the data set, each of which includes W characters. Each character represents the color of a tile as follows.
'.' - a black tile
'#' - a red tile
'@' - a man on a black tile(appears exactly once in a data set)
Output
For each data set, your program should output a line which contains the number of tiles he can reach from the initial tile (including itself).
Sample Input
6 9
....#.
.....#
......
......
......
......
......
#@...#
.#..#.
11 9
.#.........
.#.#######.
.#.#.....#.
.#.#.###.#.
.#.#..@#.#.
.#.#####.#.
.#.......#.
.#########.
...........
11 6
..#..#..#..
..#..#..#..
..#..#..###
..#..#..#@.
..#..#..#..
..#..#..#..
7 7
..#.#..
..#.#..
###.###
...@...
###.###
..#.#..
..#.#..
0 0
Sample Output
45
59
6
13
#include <iostream>
using namespace std;
int m,n;
int si,sj;
char map[30][30];
int cnt;
int dir[4][2] = {0,-1,1,0,0,1,-1,0};
int dfs(int a,int b)
{
int i;
for(i = 0 ; i < 4;i++)
{
if(a+dir[i][0] >= 0 && a+dir[i][0] < n && b+dir[i][1] >= 0 && b+dir[i][1] < m)
{
if(map[a+dir[i][0]][b+dir[i][1]] == '.')
{
map[a+dir[i][0]][b+dir[i][1]] = '#';
++cnt;
dfs(a+dir[i][0],b+dir[i][1]);
}
}
}
return cnt;
}
int main()
{
while(scanf("%d %d",&m,&n) != EOF)
{
getchar();
if(m+n == 0)
break;
int i,j;
for(i = 0;i < n ;i++)
{
for(j = 0 ; j < m;j++)
{
scanf("%c",&map[i][j]);
if(map[i][j] == '@')
si = i, sj = j;
}
getchar();
}
cnt = 1;
int ans = dfs(si,sj);
printf("%d\n",ans);
}
}