hdu4121 判断黑帅下一步会不会被红棋将军(分类讨论)

放了一个月的东西终于AC了。考虑的问题很多,由于跟网上的大神思路不一样所以看不了题解,只能自己推敲错误的原因睡觉

错误原因一:把象棋里马蹩脚的情况弄错了。这属于常识原因。

错误原因二:计算的时候没有把被黑帅吃掉的棋子去掉。。

错误原因三:在计算两个帅在同一竖线的情况时搞混了,应该既要判断黑帅走完后还有没有在同一竖线又要判断在被吃/没被吃之后的此时红黑帅有没有正面交锋。

中国象棋规则:http://jingyan.baidu.com/album/642c9d34a95995644b46f770.html?picindex=1

题目传送门:http://acm.hdu.edu.cn/showproblem.php?pid=4121

#include<iostream>
#include<algorithm>
#include<string>
#include<map>//int dx[4]={0,0,-1,1};int dy[4]={-1,1,0,0};
#include<set>//int gcd(int a,int b){return b?gcd(b,a%b):a;}
#include<vector>
#include<cmath>
#include<queue>
#include<string.h>
#include<stdlib.h>
#include<cstdio>
#define mod 1000000007
#define ll long long
using namespace std;
int ss;
int dx[4]={0,0,-1,1};int dy[4]={-1,1,0,0};
int mx[8]={-2,-2,-1,1,2,2,-1,1};
int my[8]={-1,1,-2,-2,-1,1,2,2};
//int ban1x[8]={-1,-1,-1,-1,1,1,1,1};
//int ban1y[8]={-1,1,-1,1,-1,1,-1,1};
int ban2x[8]={-1,-1,0,0,1,1,0,0};
int ban2y[8]={0,0,-1,-1,0,0,1,1};
vector<pair<int,int> >shuai,ju,ma,pao,suoyou;
pair<int,int> chidiao; //被将的下一步吃掉的位置 
int judge(int a,int b){
    for(int i=0;i<ju.size();++i){
        if(ju[i].first==chidiao.first&&ju[i].second==chidiao.second)
            continue;
        if(a==ju[i].first){
            int u=0;
            for(int j=0;j<suoyou.size();++j){
            	if(suoyou[j].first==chidiao.first&&suoyou[j].second==chidiao.second)
            		continue;
                if(suoyou[j].first==a&&suoyou[j].second>min(b,ju[i].second)&&suoyou[j].second<max(b,ju[i].second)){
                    u=1;
                    break;
                }
            }
            if(u==0)
                return 0;
        }
        else if(b==ju[i].second){
            int u=0;
            for(int j=0;j<suoyou.size();++j){
            	if(suoyou[j].first==chidiao.first&&suoyou[j].second==chidiao.second)
            		continue;
                if(suoyou[j].second==b&&suoyou[j].first>min(a,ju[i].first)&&suoyou[j].first<max(a,ju[i].first)){
                    u=1;
                    break;
                }
            }
            if(u==0)
                return 0;
        }
    }
    for(int i=0;i<ma.size();++i){
        if(ma[i].first==chidiao.first&&ma[i].second==chidiao.second)
            continue;
        for(int j=0;j<8;++j){
//            int i1=ma[i].first+ban1x[j],j1=ma[i].second+ban1y[j];
            int i2=ma[i].first+ban2x[j],j2=ma[i].second+ban2y[j];
            int u=0;
            for(int k=0;k<suoyou.size();++k){
            	if(suoyou[k].first==chidiao.first&&suoyou[k].second==chidiao.second)
            		continue;
//                if(suoyou[k].first==i1&&suoyou[k].second==j1){
//                    u=1;
//                    break;
//                }
//                else 
				if(suoyou[k].first==i2&&suoyou[k].second==j2){
                    u=1;
                    break;
                }
            } 
            if(u==1)
                continue;
            int ii=ma[i].first+mx[j],jj=ma[i].second+my[j];
            if(ii==a&&jj==b)
                return 0; 
        }
    }
    for(int i=0;i<pao.size();++i){
        if(pao[i].first==chidiao.first&&pao[i].second==chidiao.second)
            continue;
        if(pao[i].first==a){
            int s=0;
            for(int j=0;j<suoyou.size();++j){
            	if(suoyou[j].first==chidiao.first&&suoyou[j].second==chidiao.second)
            		continue;
                if(suoyou[j].first==a&&suoyou[j].second>min(pao[i].second,b)&&suoyou[j].second<max(pao[i].second,b))
                    s++;
                if(s>=2)
                    break;
            }
            if(s==1)
                return 0;
        }
        else if(pao[i].second==b){
            int s=0;
            for(int j=0;j<suoyou.size();++j){
            	if(suoyou[j].first==chidiao.first&&suoyou[j].second==chidiao.second)
            		continue;
                if(suoyou[j].second==b&&suoyou[j].first>min(pao[i].first,a)&&suoyou[j].first<max(pao[i].first,a))
                    s++;
                if(s>=2)
                    break;
            }
            if(s==1)
                return 0;
        }
    }
    return 1;
}
int cover(int a,int b){
    for(int i=0;i<4;++i){
    	chidiao=make_pair(-1,-1); 
        int ii=a+dx[i],jj=b+dy[i];
   //     cout<<ii<<" "<<jj<<endl;
        if(ii>=1&&ii<=3&&jj>=4&&jj<=6){  //帅只有一个 
        	int u=0;
            for(int j=0;j<suoyou.size();++j){
                if(suoyou[j].second==jj&&suoyou[j].first==ii){
                    u=1;
                    if(jj==shuai[0].second)
                    	u=2;
                    break;
                }
            }
            if((u==2&&ss-1==1)||(jj==shuai[0].second&&ss==1))
                continue;
	        if(u==1)
	        	chidiao=make_pair(ii,jj); 
	        if(judge(ii,jj)){
	            return 0; //将可以走这一格,不会将死 
	        }    
        }
    }
    return 1; 
}
int main(){
    int n,a,b,aa,bb;
    char c;
    while(cin>>n>>a>>b&&(n||a||b)){
        ss=0;
        shuai.clear();ju.clear();ma.clear();pao.clear();suoyou.clear();
        while(n--){
            cin>>c>>aa>>bb;
            if(c=='G')
                shuai.push_back(make_pair(aa,bb));
            else if(c=='R')
                ju.push_back(make_pair(aa,bb));
            else if(c=='H')
                ma.push_back(make_pair(aa,bb));
            else
                pao.push_back(make_pair(aa,bb));
            suoyou.push_back(make_pair(aa,bb));
        }
        for(int i=0;i<suoyou.size();++i){
            if(suoyou[i].second==shuai[0].second)
                ss++;
        }
        if(shuai[0].second==b&&ss==1)
            cout<<"NO"<<endl;
        else if(cover(a,b)==1) //会被将死
            cout<<"YES"<<endl;
        else
            cout<<"NO"<<endl; 
    }
    return 0;
}


你可能感兴趣的:(hdu4121 判断黑帅下一步会不会被红棋将军(分类讨论))