地址:http://vjudge.net/contest/view.action?cid=49557#overview
A题:
#include <iostream>
#include <queue>
using namespace std;
#define INF 100005
int main()
{
int n = 0, k = 0;
cin >> n >> k;
queue<int> q;
q.push (n);
int dist[100005] = {INF};
for (int i=0; i<INF; i++)
dist[i] = INF;
dist[n] = 0;
while (!q.empty()){
int temp = q.front();
//cout << temp <<endl;
//if (temp == k) break;
q.pop();
if (temp-1 > -1 && dist[temp - 1] > dist[temp]+1){<span style="white-space:pre"> </span>//①
dist[temp - 1] = dist [temp] + 1;
q.push (temp - 1);
if (temp-1 == k ) break;<span style="white-space:pre"> </span>//②
}
if (temp+1 < INF && dist[temp + 1] > dist[temp]+1){
dist[temp + 1] = dist [temp] + 1;
q.push (temp + 1);
if (temp+1 == k ) break;
}
if (2*temp < INF && dist[2*temp] > dist[temp]+1){
dist[2*temp] = dist [temp] + 1;
q.push (2*temp);
if (temp-1 == k ) break;
}
}
cout << dist[k] << endl;
}
①:没加判断条件,所有子节点全部插入队列,导致结果错误以及内存超限;
②:当搜索到K点时就可以跳出来,刚开始没加该条件,导致超时。
B题:
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
int ans = 1;
bool a[20][20];
int m = 0, n = 0;
void dfs (int i, int j);
int main()
{
while (cin >> m >> n && m && n){
char s[20]={'\0'};
ans = 1;
memset (a, false, sizeof (a));
int loci = 0, locj = 0;
for (int i=0; i<n; i++){
scanf ("%s", s);
for (int j=0; j<m; j++){
if (s[j] == '.') a[i][j] = true;
else if (s[j] == '#') a[i][j] = false;
else a[i][j] = false, loci = i, locj = j;
}
}
//out << loci <<" "<<locj <<endl;
dfs (loci, locj);
cout << ans << endl;
}
return 0;
}
void dfs (int i, int j)
{
if (i-1 > -1 && a[i-1][j]){
ans ++;
a[i-1][j] = false;
dfs (i-1 ,j);
//cout << i-1 <<" "<<j <<endl;
}
if (i+1 < n && a[i+1][j]){
ans ++;
a[i+1][j] = false;
dfs (i+1,j);
//cout << i+1 <<" "<<j <<endl;
}
if (j-1 > -1 && a[i][j-1]){<span style="white-space:pre"> </span>//①
ans ++;
a[i][j-1] = false;
dfs (i, j-1);
//cout << i <<" "<<j-1 <<endl;
}
if (j+1 < m && a[i][j+1]){<span style="white-space:pre"> </span>//②
ans ++;
a[i][j+1] = false ;
dfs (i, j+1);
//cout << i <<" "<<j+1 <<endl;
}
}
①②:SB错误,作死典范,,直接copy下来,忘了改值了,竟然还错了两次。。。
C题:
#include <iostream>
#include <cstdio>
#include <queue>
#define INF 100000
using namespace std;
inline bool inbond (int x) {return (0 <= x && x < 8);}
int dist[100] = {0};
queue<int> q;
void bfs (int xyb);
int main()
{
char A[4], B[4];
while (scanf ("%s %s",A, B) !=EOF){
//memset (dist, INF, 100); ① memset()的使用
for (int i=0; i<100; i++)
dist[i] = INF;
int xya = (A[0]-'a')*10 + (A[1]-'1'), xyb = (B[0]-'a')*10 + (B[1]-'1');
//cout <<xya<<xyb<<endl;
while (!q.empty()) q.pop();
q.push (xya);
dist[xya] = 0;
//cout <<xyb<<endl<< dist[xyb] << endl;
bfs (xyb);
cout << "To get from " << A << " to " << B << " takes " << dist[xyb] << " knight moves." <<endl;
}
return 0;
}
void bfs (int xyb)
{
int a[2] = {1, -1}, b[2] = {2, -2};
while (!q.empty()){
int temp = q.front ();
q.pop();
int x = temp/10, y = temp % 10;
for (int i=0; i<2; i++){
for (int j=0; j<2; j++){
if (inbond(x+a[i]) && inbond (y+b[j]) && dist[(x+a[i])*10 + (y+b[j])] > dist[temp] + 1){
dist[(x+a[i])*10 + (y+b[j])] = dist[temp] + 1;
//cout << dist[temp] << endl;
if ((x+a[i])*10 + (y+b[j]) == xyb) return ;
q.push((x+a[i])*10 + (y+b[j]));
}
}
}
for (int i=0; i<2; i++){
for (int j=0; j<2; j++){
if (inbond(x+b[i]) && inbond (y+a[j]) && dist[(x+b[i])*10 + (y+a[j])] > dist[temp] + 1){
dist[(x+b[i])*10 + (y+a[j])] = dist[temp] + 1;
//cout << dist[temp] << endl;
if ((x+b[i])*10 + (y+a[j]) == xyb) return ;
q.push((x+b[i])*10 + (y+a[j]));
}
}
}
}
}
这道题虽然过了,但是花了好长时间才写好,对广搜还不熟悉;
①:这里memset使用错误,导致一直出错。
memset()是8位8位赋值,所以,给int 赋值1 时,实际赋的值是0x 01010101, 所以memset 一般只能赋0 或 -1, 可以用memset(dist, 127, sizeof(dist))赋极大值(32639),一般情况就够用了。
D题
#include <iostream>
#include <queue>
#include <cstring>
using namespace std;
typedef struct tagPOINT{
int x,y;
int step;
}point;
int sq;
int visited[400][400];
void bfs (point now, point tar);
inline bool inbond (int a)
{
return (0 <= a && a < sq);
}
int main ()
{
int T = 0;
cin >> T;
while (T--){
memset (visited, 0, sizeof(visited));
point A,B;
cin >> sq;
cin >> A.x >> A.y >> B.x >> B.y;
A.step = 0;
if (A.x == B.x && A.y == B.y){
cout << 0 <<endl;
continue;
}
B.step = sq * sq;
visited[A.x][A.y] = 1;
bfs (A, B);
}
return 0;
}
void bfs (point now, point tar)
{
int dir[8][2]={{-2,1},{-2,-1},{-1,2},{-1,-2},{1,2},{1,-2},{2,1},{2,-1}};
queue <point> q;
q.push(now);
while (!q.empty()){
point temp = q.front(); //①
q.pop();
for (int i=0; i<8; i++){
point p;
p.x = temp.x + dir[i][0];
p.y = temp.y + dir[i][1];
//cout << p.x << " " << p.y << endl;
if (inbond(p.x) && inbond(p.y) && (visited[p.x][p.y] == 0)){
p.step = temp.step + 1;
if (p.x == tar.x && p.y == tar.y){
cout << p.step << endl;
return ;
}
q.push (p);
visited[p.x][p.y] = 1; //②
}
}
}
}
①②:延续手残风格,①处定义temp但没给值,②处忘记标记到过的地方;
E题:
e题直接过 ,就不复制代码了,但是这道题花了好长时间0.0
F题:
#include <iostream>
#include <cstring>
#include <queue>
using namespace std;
int grid[25][25], vis[25][25]; //①
const int dx[8] = {0, 0, -1, 1, 1, 1, -1, -1};
const int dy[8] = {-1, 1, 0, 0, 1 ,-1, 1, -1};
int ans;
int m, n;
void add (int x, int y);
void bfs (int x, int y);
inline bool inbond(int x, int y)
{
return (0 <= x && x < m && 0 <= y && y < n);
}
int main()
{
int x, y;
while (cin >> m >> n >> x >> y && m && n && x && y){
char stemp[25] = {'\0'};
for (int i=0; i<m; i++){
cin >> stemp;
for (int j=0; j<n; j++){
if (stemp[j] == '.') grid[i][j] = 0;
else grid[i][j] = 1;
}
}
memset(vis, 0, sizeof(vis));
ans = 0;
if (!grid[x-1][y-1]){ //②
cout << ans << endl;
continue;
}
bfs(x-1, y-1);
cout << ans << endl;
}
}
void bfs (int x, int y)
{
queue<int> q;
q.push(x*n+y);
vis[x][y] = 1;
add(x,y);
while (!q.empty()){
int temp = q.front();
q.pop();
x = temp /n, y = temp % n;
for (int i=0; i<8; i++){
int nx = x + dx[i];
int ny = y + dy[i];
if (inbond(nx, ny) && grid[nx][ny] && !vis[nx][ny]){
add(nx, ny);
q.push(nx*n+ny);
vis[nx][ny] = 1;
}
}
}
}
void add (int x, int y)
{
int nx, ny;
ans += 4;
for (int i=0; i<4; i++){
nx = x + dx[i];
ny = y + dy[i];
if (inbond(nx, ny) && grid[nx][ny])
ans--;
}
}
②:修改的时候加上了这个判断条件,不知道有没有用。