UVa 1589 Xiangqi (习题4-1)

经历了三天的拉锯战终于搞出来了

一开始写的是标记红方占据的位置,后来直接改用多个函数调用检测是否被将军

移动四个方向来检测是否有棋子可以将军,如果都不行的的话就是被将军了

其中用了两个函数来返回两个棋子之间的相对位置

然后将要检测的棋子按照那个方向移动

但是又WA了很多次,ubebug上的数据也可以过,一直找不到错误

最后通过python生成了1000组数据在udebug上面跑

才发现是马的位置把x,y方向的相对位置搞反了

同时方向为0(两个棋子在同时在某一行或者某一列的时候)没有特判

导致马和将军在同一行的时候马居然将军了。。。

(感觉自己就是个傻子。。。)

题目地址(vjudge):https://vjudge.net/problem/UVA-1589

特例数据:

5 3 4
G 9 5
H 4 4
H 8 4
C 6 7
R 4 8

7 3 4
G 10 5
R 5 2
R 2 5
H 9 3
C 6 3
H 4 9
C 7 2

0 0 0

python数据生成代码:

import random

s = {
    0:"H",
    1:"C",
    2:"R"
}

for i in range (1,1000):
    l = []
    n  = random.randint(2,7)
    b_x = random.randint(1,3)
    b_y = random.randint(4,6)
    l.append((b_x,b_y))
    t_x = random.randint(8, 10)
    t_y = random.randint(4, 6)
    l.append((t_x, t_y))
    while (len(l)<=8):
        h_x = random.randint(1, 10)
        h_y = random.randint(1, 9)
        if((h_x,h_y) in l):
            continue
        l.append((h_x, h_y))
    x = []
    t = [0,0,0]
    x.append(0)
    x.append(1)
    print(str(n)+" "+str(b_x)+" "+str(b_y))
    print("G "+str(t_x)+" "+str(t_y))
    d = 1
    while(d<n):
        now = random.randint(0,2)
        if(t[now]>=2):
            continue
        now_2 = random.randint(2,8)
        if(now_2 in x):
            continue
        x.append(now_2)
        t[now] += 1
        print(s[now] + " " + str(l[now_2][0]) + " " + str(l[now_2][1]))
        d+=1

本题AC代码:

//Decision's template
#include<cstdio>
#include<cstring>
#include<iostream>
#include<cstdlib>
#include<vector>
#include<queue>
#include<stack>
#include<algorithm>
#include<string>
#include<cmath>
#include<map>
#include<set>
using namespace std;

#define DP_maxn 16
#define maxn 1000000+10
#define INF 1000000007
#define mod 1000000007
#define mst(s,k) memset(s,k,sizeof(s))

typedef long long ll;

struct Edge{
    int from,to,dist;
    Edge(int u,int v,int d):from(u),to(v),dist(d){}
};

/*-------------------------------template End--------------------------------*/

int _map[12][11],tmp[12][11];
int n,b_x,b_y,h_x,h_y;
int t_x,t_y; 
char c;

int find_dic_colnum(int x1,int x2){       //返回第一个棋子在第二个棋子的垂直方向		 
	if(x1<x2) return -1;
	else if(x1>x2) return 1;
	else return 0;
}

int find_dic_row(int y1,int y2){           //返回水平方向 
	if(y1<y2) return -1;
	else if(y1>y2) return 1; 
	else return 0;
}

int num_between(int x1,int y1,int x2,int y2){
	int dic_x = find_dic_colnum(x1,x2);
	int dic_y = find_dic_row(y1,y2);
	int t_num = 0;
	if(y1==y2){
		for(int i = x2+dic_x;i!=x1;i+=dic_x){
			if(_map[i][y1]==0) continue; else t_num++;
		}
	}
	else if(x1==x2){
		for(int i = y2+dic_y;i!=y1;i+=dic_y){
			if(_map[x1][i]==0) continue; else t_num++;
		}
	}
	else if(x1!=x2&&y1!=y2) return -1;
	return t_num;
}

bool check_Chariot(int x,int y){
	if(x == t_x){
		int num = num_between(t_x,t_y,x,y);
		if(num == 0) return true;
		else return false;
	}
	else if(y == t_y){
		int num = num_between(t_x,t_y,x,y);
		if(num == 0) return true;
		else return false;
	}
	else if(x!=t_x&&y!=t_y) return 0;
}

bool check_Cannon(int x,int y){
	int t = num_between(t_x,t_y,x,y);
	if(t==1) return true; else return false;	
}

bool check_Horse(int x,int y){
	int dic_x = find_dic_colnum(t_x,x);
	int dic_y = find_dic_row(t_y,y);
	if(!dic_x||!dic_y) return false;
	if(_map[x+dic_x][y] == 0&&_map[x+2*dic_x][y+dic_y] == 1) return true;
	if(_map[x][y+dic_y] == 0&&_map[x+dic_x][y+2*dic_y] == 1) return true;
	return false;
}

bool check_General(int x,int y){
	if(x == t_x){
		int num = num_between(t_x,t_y,x,y);
		if(num == 0) return true;
		else return false;
	}
	else if(y == t_y){
		int num = num_between(t_x,t_y,x,y);
		if(num == 0) return true;
		else return false;
	}
	else if(x != t_x&&y != t_y) return false;
}

void copy_map(){
	for(int i = 1;i<=10;i++){
		for(int j = 1;j<=9;j++){
			_map[i][j] = tmp[i][j];
		}
	}
}

bool check(){
	bool flag = 0;
	for(int i = 1;i<=10;i++){
		for(int j = 1;j<=9;j++){
			if(_map[i][j] == 2) flag |= check_Chariot(i,j);
			else if(_map[i][j] == 3) flag |= check_Horse(i,j);
			else if(_map[i][j] == 4) flag |= check_Cannon(i,j);
			else if(_map[i][j] == 5) flag |= check_General(i,j);
		}
	}
	return flag;
}

void print_map(){
	for(int i = 1;i<=10;i++){
		for(int j = 1;j<=9;j++){
			cout<<_map[i][j];
		}
		cout<<endl;
	}
	cout<<endl;
}

bool get_ans()
{
	t_x = b_x;
	t_y = b_y;
	if(check_General(h_x,h_y)) return false;
	bool flag = 1;
	if(t_x+1<=3){
		t_x +=1;
		_map[t_x][t_y] = 1;
		_map[t_x-1][t_y] = 0;
		flag &= check();
		t_x -=1; 
	}
	copy_map();
	if(t_x-1>=1){
	    t_x -= 1;
	    _map[t_x][t_y] = 1;
	    _map[t_x+1][t_y] = 0;
	    flag &= check();
	    t_x +=1;
	}
	copy_map();
	if(t_y+1<=6){
		t_y +=1;
		_map[t_x][t_y] = 1;
		_map[t_x][t_y-1] = 0;
		flag &= check();
		t_y -=1;
	}
	copy_map();
	if(t_y-1>=4){
		t_y -=1;
		_map[t_x][t_y] = 1;
		_map[t_x][t_y+1] = 0;
		flag &= check();
		t_y +=1;
	}
	return flag;
}

int main(){
    while((scanf("%d",&n))==1&&n!=0){
    	mst(_map,0);
    	mst(tmp,0);
		cin>>b_x>>b_y;
		_map[b_x][b_y] = 1;
		tmp[b_x][b_y] = 1;
		for(int i = 1;i<=n;i++){
			cin>>c>>t_x>>t_y;
			if(c=='R') _map[t_x][t_y] = 2,tmp[t_x][t_y] = 2; //车 
			else if(c=='H') _map[t_x][t_y] = 3,tmp[t_x][t_y] = 3;  //马 
			else if(c=='C') _map[t_x][t_y] = 4,tmp[t_x][t_y] = 4;  //炮 
			else if(c=='G') _map[t_x][t_y] = 5,tmp[t_x][t_y] = 5,h_x = t_x,h_y = t_y;
		}
		if(get_ans()) cout<<"YES"<<endl;
		else cout<<"NO"<<endl;
    }	
    return 0;
}

200行代码海星,网上有的400行,然后vjudge上还有神仙100行不到就搞定的orz

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值