zoukankan      html  css  js  c++  java
  • ●UVa 1589 Xiangqi(模拟)

    ●赘述题意

    给出一个中国象棋残局,告诉各个棋子的位置,黑方只有1枚“将”,红方有至少2枚,至多7枚棋子,包含1枚“帅G”,和若干枚“车R”,“马H”,“炮C”。当前为黑方的回合,问黑方的“将”能否在移动一步后不被“将军”。

    ●题解

    本题就是一个模拟:枚举“将”向四个方向走,是否满足题意。

    但比较考察逻辑和代码能力。

    但有一个坑点:

    “将”在移动时,不能移动到与“帅”照面。

    但,恶心的数据会有输入的局面就出现将帅照面的情况,按理说,应是黑方赢了(因为轮到黑方的回合),也就是说在程序中加一个特判。但不需要这么做,或者说:不需要我们这样处理,黑“将”不能在这种情况下直接向“帅”“开大炮”…

    ●代码(没用网上的二维数组的方法,是直接枚举红棋判断)

    #include<cstdio>
    #include<cstring>
    #include<iostream>
    using namespace std;
    const int mv[4][2]={{1,0},{0,1},{-1,0},{0,-1}};
    const int hv[8][2]={{-2,1},{-1,2},{1,2},{2,1},{2,-1},{1,-2},{-1,-2},{-2,-1}};
    const int hp[8][2]={{-1,0},{0,1},{0,1},{1,0},{1,0},{0,-1},{0,-1},{-1,0}};
    struct node{
    	char ch;
    	int x,y;
    }a[10];
    int n;
    int abs(int x)
    {
    	return x>0?x:-x;
    }
    bool eat(int bx,int by,int p)
    {
    	return bx==a[p].x&&by==a[p].y;
    }
    bool CRkill(int bx,int by,int p,int t)
    {
    	if(a[p].x!=bx&&a[p].y!=by) return 0;
    	int fg=a[p].y==by,l,r,cnt=0;
    	if(!fg) l=min(a[p].y,by),r=max(a[p].y,by);
    	else l=min(a[p].x,bx),r=max(a[p].x,bx);
    	for(int i=1;i<=n;i++) if(i!=p&&!eat(bx,by,i))
    	{
    		if(!fg&&a[i].x==bx&&l<a[i].y&&a[i].y<r) cnt++;
    		if(fg&&a[i].y==by&&l<a[i].x&&a[i].x<r) cnt++;
    	}
    	return cnt==t;
    }
    bool Hkill(int bx,int by,int p)
    {
    	if(abs(bx-a[p].x)*abs(by-a[p].y)!=2) return 0;
    	int fx,fy;
    	for(int i=0;i<8;i++)
    	{
    		fx=a[p].x+hv[i][0];
    		fy=a[p].y+hv[i][1];
    		if(fx==bx&&fy==by)
    		{
    			bool fg=1;
    			for(int j=1;j<=n;j++) if(j!=p&&!eat(bx,by,j))
    				if(a[j].x==a[p].x+hp[i][0]&&a[j].y==a[p].y+hp[i][1]) fg=0;
    			if(fg) return 1;
    		}
    	}
    	return 0;
    }
    bool live(int bx,int by)
    {
    	for(int i=1;i<=n;i++) if(!eat(bx,by,i))
    	{
    		if(a[i].ch=='G'&&CRkill(bx,by,i,0)) return 0;
    		if(a[i].ch=='R'&&CRkill(bx,by,i,0)) return 0;
    		if(a[i].ch=='C'&&CRkill(bx,by,i,1)) return 0; 
    		if(a[i].ch=='H'&&Hkill(bx,by,i)) return 0;
    	}
    	return 1;
    }
    bool check(int bx,int by)
    {
    	int fx,fy;
    	for(int i=0;i<4;i++)
    	{
    		fx=bx+mv[i][0];
    		fy=by+mv[i][1];
    		if(fx<1||fx>3||fy<4||fy>6) continue;
    		if(live(fx,fy)) return 0;		
    	}
    	return 1;
    }
    int main()
    {
    	int bx,by;
    	while(1)
    	{
    		cin>>n>>bx>>by;
    		if(!n&&!bx&&!by) break;
    		for(int i=1;i<=n;i++) 
    			cin>>a[i].ch>>a[i].x>>a[i].y;
    		if(check(bx,by)) cout<<"YES"<<endl;
    		else cout<<"NO"<<endl;
    	}
    	return 0;
    }
  • 相关阅读:
    和菜鸟一起学产品之产品经理的自我管理能力
    和菜鸟一起学产品之产品经理的工作职责
    遗传算法解决TSP问题实现以及与最小生成树的对比
    双系统或三系统:Grub Rescue修复方法
    err:安装程序试图挂载映像 1(缺少ISO 9660图像)
    OpenCV手写数字字符识别(基于k近邻算法)
    最小生成树
    ubuntu12.04:Tomcat 7服务器:手动安装
    ubuntu12.04:jdk7:手动安装
    ubuntu12.04:Mysql数据库:手动安装
  • 原文地址:https://www.cnblogs.com/zj75211/p/7463383.html
Copyright © 2011-2022 走看看