炮兵阵地(acm.pku1185)解法
2012-04-10 19:38
323 查看
炮兵阵地(acm.pku1185)解法与状态DP原理
# include <stdio.h> # include <malloc.h> void Input(char*,int,int); void SetSolder(char*,int,int); void InitChoice(int*,char*,int,int); void FindBestPlace(int*,int,int,int); int Calculate(int*,int,int,int); void Connect(int*,int,int*,int,int); int main(int argc,char* argv[]){ char *Map;//Map为地图数组 int n,m;//n代表地图的高,m代表地图的宽 printf("请输入地图的高度及宽度; "); scanf("%d %d",&n,&m);getchar(); Map=(char*)malloc((n*m)*sizeof(char)); printf("\n绘制地图,h表示山,p表示平原:\n"); Input(Map,n,m); SetSolder(Map,n,m); free(Map); return 1; } void Input(char* Map,int n,int m){ //用来对地图进行输入 int i,j; printf("\n每行%d个字符,共计%d行\n",m,n); for(j=0;j<n;++j){ for(i=0;i<m;++i) Map[j*m+i]=getchar(); getchar(); } } void SetSolder(char *Map,int n,int m){ //在平原上进行设置炮兵的函数,也是本程序的关键 int *Choice,pi,num;//choice为选择数组名,平原初值为-1,在次平原上放炮兵其值为1,确定不在上放炮兵时为0 Choice=(int*)malloc((n*m)*sizeof(int)); InitChoice(Choice,Map,n,m); for(pi=0;pi<n*m;++pi) if(Choice[pi]==-1) FindBestPlace(Choice,pi,n,m); for(pi=0,num=0;pi<n*m;++pi) if(Choice[pi]==1) ++num; printf("\n\n最多可放人数: %d\n",num); free(Choice); } void InitChoice(int Choice[],char *Map,int n,int m){ //用来初始化选择数组int Choice[],大小由输入的n*m值确定 int pi; for(pi=0;pi<n*m;++pi) if(Map[pi]=='h') Choice[pi]=-2; else Choice[pi]=-1; } void FindBestPlace(int* Choice,int pi,int n,int m){ //以平原pi为起点判断与之相连的平原选择哪一个 int place[9],minnum=0,cout,pj,k,curpios=pi; minnum=Calculate(Choice,pi,n,m); if(minnum==0) Choice[pi]=1; else{ Connect(Choice,pi,place,n,m); for(k=1;k<=place[0];++k){ pj=place[k]; cout=Calculate(Choice,pj,n,m); if(cout<minnum){ curpios=pj; minnum=cout; } } if(curpios!=pi) Connect(Choice,curpios,place,n,m); Choice[curpios]=1; for(k=1;k<=place[0];++k){ pj=place[k]; Choice[pj]=0; } } } int Calculate(int* Choice,int pi,int n,int m){ //计算射程范围内平原个数 int num=0; int upone=pi-m,uptow=pi-2*m, downone=pi+m,downtow=pi+2*m, leftone=pi-1,lefttow=pi-2, rightone=pi+1,righttow=pi+2; if(upone>=0&&Choice[upone]==-1) ++num; if(uptow>=0&&Choice[uptow]==-1) ++num; if(downone<n*m&&Choice[downone]==-1) ++num; if(downtow<n*m&&Choice[downtow]==-1) ++num; if(pi%m!=0&&Choice[leftone]==-1) ++num; if(pi%m!=0&&leftone%m!=0&&Choice[lefttow]==-1) ++num; if(rightone%m!=0&&Choice[rightone]==-1) ++num; if((pi+1)%m!=0&&(rightone+1)%m!=0&&Choice[righttow]==-1) ++num; return num; } void Connect(int* Choice,int pi,int* place,int n,int m){ //把相连的平原防入数组 int i=0, upone=pi-m,uptow=pi-2*m, downone=pi+m,downtow=pi+2*m, leftone=pi-1,lefttow=pi-2, rightone=pi+1,righttow=pi+2; if(upone>=0&&Choice[upone]==-1) place[++i]=upone; if(uptow>=0&&Choice[uptow]==-1) place[++i]=uptow; if(downone<n*m&&Choice[downone]==-1) place[++i]=downone; if(downtow<n*m&&Choice[downtow]==-1) place[++i]=downtow; if(pi%m!=0&&Choice[leftone]==-1) place[++i]=leftone; if(pi%m!=0&&leftone%m!=0&&Choice[lefttow]==-1) place[++i]=lefttow; if(rightone%m!=0&&Choice[rightone]==-1) place[++i]=rightone; if((pi+1)%m!=0&&(rightone+1)%m!=0&&Choice[righttow]==-1) place[++i]=righttow; place[0]=i; }
相关文章推荐
- PKU 1185 炮兵阵地
- pku 1185 炮兵阵地 压缩dp 解题报告
- pku 1185 炮兵阵地 状压DP
- PKU 1185 炮兵阵地 经典状态压缩dp
- pku1185炮兵阵地
- pku 1185 炮兵阵地 压缩dp 解题报告
- pku 1185 炮兵阵地
- poj 1185 炮兵阵地
- poj 1185 炮兵阵地(DP-状态DP)
- poj 1185 && NYOJ 85 炮兵阵地(状态压缩dp)
- Poj 1185 炮兵阵地 状态压缩
- poj 1185 炮兵阵地 状态压缩dp
- 炮兵阵地 POJ - 1185 (状压dp)
- 100道动态规划——27 POJ 1185 炮兵阵地 状态压缩,预处理,滚动数组
- 状态压缩dp入门题 POJ 1185 炮兵阵地
- poj 1185 炮兵阵地 状压dp
- poj 1185 炮兵阵地 状压dp
- POJ1185炮兵阵地
- 【POJ - 1185 】炮兵阵地 【状压DP】
- poj 1185 炮兵阵地 状压dp