题目A: 原站地址http://acm.fzu.edu.cn/problem.php?pid=1056
该题以大家熟悉的扫雷游戏为背景,让我们完成已知地雷出现位置的情况下,得到各个方块中的数据。
结合实例我们不难看出程序的意思让我们输出除地雷以外所有其他方格周围的八个方格上的地雷总数。
实现方法:统计每个‘.’处周围的八个位置的地雷总数,然后输出即可。
PS:多实例输入,结束条件为n和m都为0;
需要注意的是每个实例后有一个空格。
参考代码:
1 #include<stdio.h> 2 #include<string.h> 3 #define N 105 4 char map[N][N]; 5 int ans[N][N]; 6 int n,m; 7 int dir[8][2]={-1,-1, 0,-1, 1,-1, 1,0, 1,1, 0,1, -1,1, -1,0};//枚举其周围的8个方向位置 8 void handle(int x,int y) 9 { 10 int i; 11 int l,c; 12 int count=0; 13 for(i=0;i<8;i++)//对周围的8个位置依次进行判断是否是地雷 14 { 15 l=x+dir[i][0]; 16 c=y+dir[i][1]; 17 if(l>=0&&l<n&&c>=0&&c<m) 18 { 19 if(map[l][c]=='*') 20 count++; 21 } 22 } 23 ans[x][y]=count; 24 25 } 26 int main() 27 { 28 while(scanf("%d%d",&n,&m)!=EOF) 29 { 30 getchar();//接受输入行的最后的回车 31 if(n==0&&m==0) break;//测试结束条件 32 int i,j; 33 for(i=0;i<n;i++) 34 scanf("%s",map[i]); 35 memset(ans,0,sizeof(ans)); 36 for(i=0;i<n;i++) 37 { 38 for(j=0;j<m;j++) 39 { 40 if(map[i][j]=='*')//如果是地雷将其标记 41 ans[i][j]=-1; 42 else//否则统计其周围的地雷数 43 handle(i,j); 44 } 45 } 46 47 for(i=0;i<n;i++) 48 { 49 for(j=0;j<m;j++) 50 { 51 if(ans[i][j]==-1) 52 printf("*"); 53 else 54 printf("%d",ans[i][j]); 55 } 56 printf("\n"); 57 } 58 printf("\n");//每组实例后的空格 59 } 60 return 0; 61 } 62 63 64
题目B: 题目地址http://acm.uestc.edu.cn/problem.php?pid=1023
本题可以不用多实例输入;
参考代码:
1 #include<stdio.h> 2 #include<string.h> 3 int handle(int m) 4 { 5 if(m>=90) 6 return 4; 7 else if(m>=80) 8 return 3; 9 else if(m>=70) 10 return 2; 11 else if(m>=60) 12 return 1; 13 else 14 return 0; 15 } 16 int main() 17 { 18 int n; 19 int sum,t; 20 double ans; 21 scanf("%d",&n); 22 23 sum=0;t=0; 24 int i; 25 for(i=0;i<n;i++) 26 { 27 int c,s; 28 scanf("%d%d",&c,&s); 29 sum+=c*handle(s); 30 t+=c; 31 } 32 ans=1.0*sum/t; 33 printf("%.2lf\n",ans); 34 35 return 0; 36 }
题目C:题目地址http://acm.fzu.edu.cn/problem.php?pid=1205
题意:在一个n*m的迷宫里,找出从a到b的最短路径的长度,和有多少种这样的最短路径。
这里介绍一种比较易于理解的做法:先用BFS计算出最短路的长度,得出长度后,用DFS搜出有多少种不同的最短路径。
不过这种做法如果不做任何优化就会超时,需要做相应的优化。
PS:BFS(广度优先搜索)算法常用于这种迷宫的搜索,即前一步到下一步花费的代价(时间)是相同的,BFS算法是一种由原点向四周步步搜索层层推进的算法,这样直到目的地。所以在这种迷宫的搜索中用BFS计算出的两点的距离就是最短距离。在搜索的过程中需要把走过的方格标记,防止程序走向死循环。
DFS(深搜优先搜索)算法是由当前的搜索点一直搜索到本轮搜索结束,然后进行下一个点的搜索,同样进行BFS时也需要标记,但是当上一个搜索点压人搜索队列中后,被压入点的标记就要取消,防止影响下一轮的搜索。BFS是非常耗时的,需要根据具体的题目做出优化。不然往往会超时。
参考代码:
1 #include<iostream> 2 #include<cstring> 3 #include<cstdio> 4 #include<queue> 5 using namespace std; 6 int dir[4][2]={0,1,0,-1,1,0,-1,0}; 7 struct node//记录迷宫原点到x,y位置所走步数 8 { 9 int x,y,step; 10 }; 11 #define N 100 12 int n,m,k; 13 int map[N][N];//DFS中标记数组 14 int mark[N][N];//BFS中标记数组 15 int x1,x2,y1,y2;//起始位置坐标 16 int ways,min_step;//记录最短路径的不同种类 最短步数 17 int BFS()//最短路计算最短路径的长度 18 { 19 node cur,next; 20 queue<node>q; 21 int x,y,i; 22 cur.x=x1;cur.y=y1;cur.step=0; 23 q.push(cur); 24 mark[x1][y1]=1; 25 while(!q.empty()) 26 { 27 cur=q.front(); 28 q.pop(); 29 for(i=0;i<4;i++) 30 { 31 next.x=x=cur.x+dir[i][0]; 32 next.y=y=cur.y+dir[i][1]; 33 if(x>=1&&x<=n&&y>=1&&y<=m&&mark[x][y]==0) 34 { 35 if(x==x2&&y==y2) 36 { 37 printf("%d\n",cur.step+1); 38 min_step=cur.step+1; 39 return 1; 40 } 41 next.step=cur.step+1; 42 q.push(next); 43 mark[x][y]=1; 44 } 45 46 } 47 48 } 49 printf("No Solution!\n"); 50 return 0; 51 } 52 void DFS(int x,int y,int step) 53 { 54 if(x==x2&&y==y2&&step==min_step) 55 { 56 ways++; 57 return ; 58 } 59 if(step+(x2>x?x2-x:x-x2)+(y2>y?y2-y:y-y2)>min_step) return ;//DFS的优化,如果少了这个事会超时的 60 int xx,yy,i; 61 for(i=0;i<4;i++) 62 { 63 xx=x+dir[i][0]; 64 yy=y+dir[i][1]; 65 if(xx>=1&&xx<=n&&yy>=1&&yy<=m&&map[xx][yy]==0) 66 { 67 map[xx][yy]=1;//标记 68 DFS(xx,yy,step+1);//压入搜索队列 69 map[xx][yy]=0;//取消标记 70 } 71 } 72 73 } 74 75 int main() 76 { 77 while(scanf("%d%d%d",&n,&m,&k)!=EOF) 78 { 79 memset(mark,0,sizeof(mark)); 80 memset(map,0,sizeof(mark)); 81 int i; 82 for(i=1;i<=k;i++)//标记不能走的门 83 { 84 int a,b; 85 scanf("%d%d",&a,&b); 86 map[a][b]=1; 87 mark[a][b]=1; 88 } 89 scanf("%d%d",&x1,&y1); 90 scanf("%d%d",&x2,&y2); 91 ways=0; 92 int flag; 93 if(x1==x2&&y1==y2)//考虑起点和原点重合的情况 94 printf("%d\n%d\n",0,0); 95 else 96 flag=BFS(); 97 if(flag) 98 { 99 DFS(x1,y1,0); 100 printf("%d\n",ways); 101 } 102 103 } 104 return 0; 105 }
题目D:http://acm.hdu.edu.cn/showproblem.php?pid=2093
呵呵!很有意思的一题,很实用的。
本题应该归于排序+字符串处理。
本题的关键两点 sscanf函数的使用 排序算法
好吧!我的习惯不是很好,喜欢C、C++混合使用;
参考代码:
1 #include<iostream> 2 #include<cstring> 3 #include<cstdio> 4 #include<algorithm> 5 using namespace std; 6 struct node{ 7 char name[15]; 8 int ac; 9 int time; 10 }s[500]; 11 int n,m; 12 bool cmp(node a,node b) 13 { 14 if(a.ac!=b.ac) 15 return a.ac>b.ac; 16 else if(a.time!=b.time) 17 return a.time<b.time; 18 else 19 return strcmp(a.name,b.name)<0; 20 } 21 22 int main() 23 { 24 memset(s,0,sizeof(s)); 25 scanf("%d%d",&n,&m); 26 getchar(); 27 int i=0; 28 while(scanf("%s",s[i].name)!=EOF) 29 { 30 if(strcmp(s[i].name,"end")==0) break;//为了调试观查结果,特意加了一句 31 char str[15]; 32 int j; 33 34 for(j=0;j<n;j++) 35 { 36 scanf("%s",str); 37 int a,b; 38 int ans; 39 ans=sscanf(str,"%d(%d)",&a,&b); 40 if(ans==2) 41 { 42 s[i].ac++; 43 s[i].time=s[i].time+a+b*m; 44 } 45 else if(ans==1&&a>0) 46 { 47 s[i].ac++; 48 s[i].time+=a; 49 } 50 } 51 i++; 52 } 53 sort(s,s+i,cmp); 54 for(int k=0;k<i;k++) 55 printf("%-10s %2d %4d\n",s[k].name,s[k].ac,s[k].time); 56 return 0; 57 }