• Rats codeforces 254D


    【原题地址】: codeforces254D

    【题目大意】:

    你有两个炸弹,每个炸弹只能炸到与炸弹相距 (d) (曼哈顿距离)的老鼠,问在哪两个点放炸弹,能炸死所有老鼠(炸弹不能都放在一个位置),若不能输出 (-1)

    【题解】:

    我们首先可以知道,(d) 的范围比较小,当老鼠过多时就炸不完了,所以当老鼠个数大于 (290) 时直接输出 (-1)
    我们对每只老鼠所在的位置进行 (bfs) 向外扩展 (d) 格,对于搜到的每个点进行编号,并且记录这个点能炸到哪些老鼠
    处理完过后直接枚举,输出答案
    如下
    va[num][k] 数组用于记录 (num) 号点能否炸到第 (k) 只老鼠
    vx[num] vy[num] 分别用于记录 (num) 号点的坐标
    reach[x][y] 表示点 ((x,y)) 有没有进行重新编号

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<vector>
    #include<queue>
    using namespace std;
    const int max_rats=290;
    const int maxn=1000+10;
    struct node
    {
    	int x,y,d;
    	node(int xx=0,int yy=0,int dd=0){
    		x=xx,y=yy,d=dd;
    	};
    };
    vector<node>rats;
    int n,m,d,cnt_rats=0,size=0;
    int map[maxn][maxn];
    char s[maxn][maxn];
    int reach[maxn][maxn];
    int vx[max_rats*max_rats],vy[max_rats*max_rats];
    bool va[max_rats*max_rats][max_rats];
    bool vis[maxn][maxn];
    const int dx[4]={0,1,-1,0},dy[4]={1,0,0,-1};
    void put_set(int x,int y,int type)//(x,y)能炸到type号老鼠
    {
    	if(!reach[x][y])//未编过号
    	{
    		va[++size][type]=1;
    		vx[size]=x;
    		vy[size]=y;
    		return ;
    	}
    	for(int i=1;i<=size;i++)
    	if(vx[i]==x&&vy[i]==y){
    		va[i][type]=1;
    		break;
    	}
    }
    void bfs(int type,node st)//对每只老鼠进行处理
    {
    	memset(vis,0,sizeof(vis));
    	queue<node>q;
    	q.push(st);
    	vis[st.x][st.y]=1;
    	while(!q.empty())
    	{
    		node u=q.front();
    		q.pop();
    		put_set(u.x,u.y,type);
    		reach[u.x][u.y]=1;
    		if(u.d==d)continue;
    		for(int i=0;i<4;i++)
    		{
    			int x=u.x+dx[i],y=u.y+dy[i];
    			if(x<1||x>n||y<1||y>m||vis[x][y]||map[x][y])continue;
    			vis[x][y]=1;
    			q.push(node(x,y,u.d+1));
    		}
    	}	
    }
    int main()
    {
    	freopen("input.txt","r",stdin);
    	freopen("output.txt","w",stdout);
    	int ans1,ans2,find_ans=0;
    	scanf("%d%d%d",&n,&m,&d);
    	for(int i=1;i<=n;i++)
    	{
    		scanf("%s",s[i]+1);
    		for(int j=1;j<=m;j++)
    		if(s[i][j]=='R')cnt_rats++;
    	}
    	if(cnt_rats>max_rats){printf("-1
    ");return 0;}
    	for(int i=1;i<=n;i++)
    	for(int j=1;j<=m;j++)
    	{
    		map[i][j]=0;
    		if(s[i][j]=='X')map[i][j]=1;
    		if(s[i][j]=='R')rats.push_back(node(i,j,0));
    	}
    	for(int i=0;i<cnt_rats;i++)
    	bfs(i,rats[i]);
    	if(size==1)//只有一个点能炸到老鼠
    	{
    		for(int i=0;i<cnt_rats;i++)
    		if(va[1][i]==0)
    		{
    			printf("-1
    ");
    			return 0;
    		}
    		printf("%d %d ",vx[1],vy[1]);
    		for(int i=1;i<=n;i++)//寻找一个与之前点不同的点
    		for(int j=1;j<=m;j++)
    		{
    			if(map[i][j]||(i==vx[1]&&j==vy[1]))continue;
    			printf("%d %d
    ",i,j);
    			return 0;
    		}
    	}
    	for(int i=1;i<size;i++)
    	{
    		
    		for(int j=i+1;j<=size;j++)//枚举能炸到老鼠的两个不同的点
    		{
    			find_ans=1;
    			for(int k=0;k<cnt_rats;k++)
    			if(va[i][k]==0&&va[j][k]==0)//有一只老鼠不能炸到
    			{
    				find_ans=0;
    				break;
    			}
    			if(find_ans){
    				ans1=i;
    				ans2=j;
    				break;
    			}
    		}	
    		if(find_ans)break;
    	}
    	if(find_ans)printf("%d %d %d %d
    ",vx[ans1],vy[ans1],vx[ans2],vy[ans2]);
    	else printf("-1
    ");
    }
    
  • 相关阅读:
    PostgreSQL在何处处理 sql查询之三十四
    PostgreSQL在何处处理 sql查询之三十八
    PostgreSQL在何处处理 sql查询之三十五
    网站设计必知的65条原则
    网站CI形象的定位
    五句话定会改变你的人生
    网站申明要注意!
    发个不要数据库的论坛
    关于猴子拿桃子的问题
    企业建站的几个误区!
  • 原文地址:https://www.cnblogs.com/Harry-bh/p/8831848.html
Copyright © 2020-2023  润新知