经历了三天的拉锯战终于搞出来了
一开始写的是标记红方占据的位置,后来直接改用多个函数调用检测是否被将军
移动四个方向来检测是否有棋子可以将军,如果都不行的的话就是被将军了
其中用了两个函数来返回两个棋子之间的相对位置
然后将要检测的棋子按照那个方向移动
但是又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