P3693求助
  • 板块学术版
  • 楼主A_better_world
  • 当前回复1
  • 已保存回复1
  • 发布时间2022/12/23 10:21
  • 上次更新2023/10/24 06:53:36
查看原帖
P3693求助
616872
A_better_world楼主2022/12/23 10:21

P3693 琪露诺的冰雪小屋

WA了11个点,求各位大佬当我看看哪错了!!!

#include<stdio.h>
#include<string.h>
#include<stdbool.h>
 
void ice_barrage(int r, int c, int d, int s);
void make_ice_block(void);
void put_ice_block(int r, int c, int h);
void remove_ice_block(int r, int c, int h);
void make_roof(void);
//处理对应操作 

void dfs(int x, int y, int z); 
//计算连通块数量 

const int x[8]={-1,-1,0,1,1,1,0,-1}, y[8]={0,-1,-1,-1,0,1,1,1};
const int xx[6]={-1,1,0,0,0,0}, yy[6]={0,0,-1,1,0,0}, zz[6]={0,0,0,0,-1,1};
bool ice[20][20][25], vis[20][20][25], perfect=true;
char str[20];
int n, hm, hr, hc, hx, hy, m, ice_cnt, highest, arr[20][20];
int main()
{
	scanf("%d%d%d%d%d%d%d", &n, &hm, &hr, &hc, &hx, &hy, &m);
	for(int i=0; i<m; i++)
	{
		scanf(" %s", str);
		if(strcmp(str, "ICE_BARRAGE")==0)
		{
			int r, c, d, s;
			scanf("%d%d%d%d", &r, &c, &d, &s);
			ice_barrage(r, c, d, s);			
		}
		else if(strcmp(str, "MAKE_ICE_BLOCK")==0)
		{
			make_ice_block();
		}
		else if(strcmp(str, "PUT_ICE_BLOCK")==0)
		{
			int r, c, h;
			scanf("%d%d%d", &r, &c, &h);
			put_ice_block(r, c, h);
		}
		else if(strcmp(str, "REMOVE_ICE_BLOCK")==0)
		{
			int r, c, h;
			scanf("%d%d%d", &r, &c, &h);
			remove_ice_block(r, c, h);
		}
		else if(strcmp(str, "MAKE_ROOF")==0)
		{
			make_roof();
		}
	}
	return 0;
}

void ice_barrage(int r, int c, int d, int s) //冰雪弹幕 
{
	int px=r, py=c, cnt=0;
	for(int i=0; i<=s; i++)
	{
		if(px<0 || py<0 || px>=n || py>=n || ice[px][py][0]) //越界或有冰砖退出 
			break;
		if(arr[px][py] < 4)
			arr[px][py]++, cnt++; //记录 
		px+=x[d], py+=y[d];
	}
	printf("CIRNO FREEZED %d BLOCK(S)\n", cnt);
	return;
}

void make_ice_block(void) //寻找合法格并制作冰砖 
{
	int cnt=0;
	for(int i=0; i<n; i++)
	{
		for(int j=0; j<n; j++)
		{
			if(arr[i][j] == 4) //可以制作冰砖 
				arr[i][j] = 0, cnt++;
		}
	}
	ice_cnt += cnt; //更新冰砖总数 
	printf("CIRNO MADE %d ICE BLOCK(S),NOW SHE HAS %d ICE BLOCK(S)\n", cnt, ice_cnt);
}

void put_ice_block(int r, int c, int h) //放置冰砖 
{
	if(ice_cnt == 0) //没有冰砖 
	{
		puts("CIRNO HAS NO ICE_BLOCK");
		return;
	}
	else if((h!=0 && !((h<=hm-2&&ice[r][c][h+1]) || (h!=0&&ice[r][c][h-1]) || (r+1<n&&ice[r+1][c][h]) || (r!=0&&ice[r-1][c][h])
		|| (c+1<n&&ice[r][c+1][h]) || (c!=0&&ice[r][c-1][h]))) || ice[r][c][h]) //浮空或位置被占 
	{
		puts("BAKA CIRNO,CAN'T PUT HERE");
	}
	else if(r<hr||r>hr+hx-1||c<hc||c>hc+hy-1) //超出建屋范围 
	{
		puts("CIRNO MISSED THE PLACE");
		highest = highest < h ? h : highest;
		ice_cnt--, ice[r][c][h] = true;
	}
	else if(hr+1<=r&&r<=hr+hx-2&&hc+1<=c&&c<=hc+hy-2) //放在小屋内 
	{
		puts("CIRNO PUT AN ICE_BLOCK INSIDE THE HOUSE");
		highest = highest < h ? h : highest;
		ice_cnt--, ice[r][c][h] = true;
	}
	else //no problem 
	{
		printf("CIRNO SUCCESSFULLY PUT AN ICE_BLOCK,NOW SHE HAS %d ICE_BLOCK(S)\n", --ice_cnt);
		highest = highest < h ? h : highest;
		ice[r][c][h] = true;
	}
	if(h==0 && ice[r][c][h]) //冰砖放在地面上 
	{
		arr[r][c] = 0; //清除该处寒冷度 
	}
}

void remove_ice_block(int r, int c, int h)  
{
	if(!ice[r][c][h]) //冰砖不存在 
	{
		puts("BAKA CIRNO,THERE IS NO ICE_BLOCK");
	}
	else
	{
		ice[r][c][h]=false, ice_cnt++;
		puts("CIRNO REMOVED AN ICE_BLOCK");
	} 
}

void make_roof(void) //建造屋顶 
{
	int cnt=0, place=0;
	for(int i=hr; i<hr+hx; i++) //计算需要的冰砖数量 
	{
		for(int j=hc; j<hc+hy; j++)
		{
			if(!ice[i][j][highest+1])
			{
				cnt++, ice[i][j][highest+1]=true;
			}
		}
	}
	place = hx*hy*highest; //计算屋内空间 
	if(ice_cnt < cnt) //冰砖不够 
	{
		puts("SORRY CIRNO,NOT ENOUGH ICE_BLOCK(S) TO MAKE ROOF");
	}
	else if(highest < 2 || place < 2) //屋子太小 
	{
		puts("SORRY CIRNO,HOUSE IS TOO SMALL");
	}
	else // no problem
	{
		int block=0;
		ice_cnt -= cnt;
		int k1=0, k2=0;
		for(int i=hr+1; i<hr+hx-1; i++) //计算屋内多余冰砖 
		{
			for(int j=hc+1; j<hc+hy-1; j++)
			{
				for(int k=0; k<highest; k++)
				{
					if(ice[i][j][k])
					{
						k1++;
						ice[i][j][k]=false;
					}
				}
			}
		} 
		for(int i=0; i<n; i++) //计算屋外多余冰砖 
		{
			for(int j=0; j<n; j++)
			{
				for(int k=0; k<hm; k++)
				{
					if((i<hr&&j<hc||i>hr+hx&&j>hc+hy)&&ice[i][j][k])
					{
						k2++;
						ice[i][j][k]=false;
					}
				}
			}
		}
		printf("%d ICE_BLOCK(S) INSIDE THE HOUSE NEED TO BE REMOVED\n", k1);
		printf("%d ICE_BLOCK(S) OUTSIDE THE HOUSE NEED TO BE REMOVED\n", k2);
		ice_cnt += k1+k2;
//		memset(vis, 0, sizeof(vis));
//		for(int i=hr; i<hr+hx; i++)
//		{
//			for(int j=hc; j<hc+hy; j++)
//			{
//				for(int k=0; k<highest; k++)
//				{
//					if(ice[i][j][k] && !vis[i][j][k])
//					{
//						dfs(i, j, k);
//						block++;
//					}
//				}
//			}
//		}
//		if(block > 1) //如果连通块数量多于一个,则屋顶将会塌陷(浮空) 
//		{
//			puts("SORRY CIRNO,HOUSE IS BROKEN WHEN REMOVING BLOCKS");
//		}
//		else //no problem*2
//		{
			int fix=0, fix_corner=0, door_x=0, door_y=0;
			bool has_door=false, fake_door=false;
			for(int i=hr+1; i<hr+hx-1; i++) //计算需要填补的冰砖数量 
			{
				for(int j=0; j<=highest; j++)
				{
					if(!ice[i][hc][j])
					{
						fix++;
						perfect=false;
						ice[i][hc][j]=true;
					}
					if(!ice[i][hc+hy-1][j])
					{
						fix++;
						perfect=false;
						ice[i][hc+hy-1][j]=true;
					}
				}
			}
			for(int i=hc+1; i<hc+hy-1; i++)
			{
				for(int j=0; j<=highest; j++)
				{
					if(!ice[hr][i][j])
					{
						fix++;
						perfect=false;
						ice[hr][i][j]=true;
					}
					if(!ice[hr+hx-1][i][j])
					{
						fix++;
						perfect=false;
						ice[hr+hx-1][i][j]=true;
					}
				}
			}
			for(int i=hr+1; i<hr+hx-1 && !has_door; i++) //计算是否存在可以开门的位置并记录 
			{
				if(!ice[i][hc][0] && !ice[i][hc][1])
				{
					has_door = true;
					door_x = i, door_y = hc;	
				}
				else if(!ice[i][hc][0] || !ice[i][hc][1])
				{
					fake_door = true; 
				}	
				if(!ice[i][hc+hy-1][0] && !ice[i][hc+hy-1][1])
				{
					has_door = true;
					door_x = i, door_y = hc+hy-1;
				}
				else if(!ice[i][hc+hy-1][0] || !ice[i][hc+hy-1][1])
				{
					fake_door = true;
				}
			}
			for(int i=hc+1; i<hc+hy-1 && !has_door; i++)
			{
				if(!ice[hr][i][0] && !ice[hr][i][1])
				{
					has_door = true;
					door_x = hr, door_y = i;	
				}
				else if(!ice[hr][i][0] || !ice[hr][i][1])
				{
					fake_door = true;	
				}	
				if(!ice[hr+hx-1][i][0] && !ice[hr+hx-1][i][1])
				{
					has_door = true;
					door_x = i, door_y = i;
				}
				else if(!ice[hr+hx-1][i][0] || !ice[hr+hx-1][i][1])
				{
					fake_door = true;
				}
			}
			for(int i=hr; i<hr+hx; i++) //计算拐角是否需要修复
			{
				for(int j=hc; j<hc+hy; j++)
				{
					if((i!=hr&&i!=hr+hx-1)||(j!=hc&&j!=hc+hy-1)) //位置不是拐角,继续枚举下个位置 
					{
						continue;
					}
					for(int k=0; k<=highest; k++) //计算拐角空缺的冰砖数量 
					{
						if(!ice[i][j][k])
						{
							fix_corner++;
						}
					} 
				}
			}
			if(ice_cnt < fix) //冰砖不足 
			{
				puts("SORRY CIRNO,NOT ENOUGH ICE_BLOCKS TO FIX THE WALL");
			}
			else //小屋成功建成 
			{
				puts("GOOD JOB CIRNO,SUCCESSFULLY BUILT THE HOUSE");
				if(has_door) //判断是否有门 
				{
					puts("DOOR IS OK");
				}
				else
				{
					puts("HOUSE HAS NO DOOR");
					perfect = false;
					if(fake_door)
						fix -= 1;
					else
						ice_cnt += 2; 
				}
				if(fix <= 0) //判断墙壁是否需要修补 
				{
					puts("WALL IS OK");
					fix = 0;
				}
				else
				{
					puts("WALL NEED TO BE FIXED");
					perfect = false;
				}
				if(!fix_corner) //判断拐角是否需要修补 
				{
					puts("CORNER IS OK");
				}
				else
				{
					puts("CORNER NEED TO BE FIXED");
					perfect = false;
				}
				ice_cnt -= fix+fix_corner;
				ice_cnt = ice_cnt > 0 ? ice_cnt : 0;
				//更新冰块数量 
				printf("CIRNO FINALLY HAS %d ICE_BLOCK(S)\n", ice_cnt);
				if(perfect)
				{
					puts("CIRNO IS PERFECT!");
				}
			//}
		}
	} 
}

void dfs(int x, int y, int z)
{
	if(x<0||y<0||z<0||x>=n||y>=n||z>highest||!ice[x][y][z]||vis[x][y][z]) //越界或重复直接退出 
		return; 
	vis[x][y][z] = true; //标记
	for(int i=0; i<6; i++) //向六个方向枚举拓展 
	{
		int px=x+xx[i], py=y+yy[i], pz=z+zz[i];
		dfs(px, py, pz); //递归调用 
	} 
}
2022/12/23 10:21
加载中...