象棋UVa1589
题目:给定一个棋局,黑方仅剩一将,红方剩2~7个棋子,类型有G(帅)、H(马)、
R(车)、C(炮),现轮黑方走,判断黑方下完后是否为输,输则输出YES,不输则
输出NO。输入第一行N,x,y,接下去行,每行类型(ch),坐标(x,y),以0 0 0为输
入终止。
sample:
输入:
5 1 5
G 9 6
C 8 8
C 1 8
R 2 3
R 10 1
4 1 5
G 10 4
C 6 5
H 5 5
R 1 1
输出
NO
YES
程序通过了uDebug上的全部样例。
题目本身不难,只是繁杂,还有一个小坑点,不输包括了红方杀不了黑将和黑将直接杀了红帅两种情况,所以程序要囊括2种,第一次写的时候没判断赢的情况。在写判断赢的情况的时候,还傻乎乎的在想吃了对方的帅黑将还能不能活,哎!太蠢了。
思路:
①先用mesh[][]做好棋盘
②判断黑将能不能赢
③判断四个方位能不能走,能走判断会不会被吃
小细节:注意改动棋盘,不然在判断会不会被吃时会有出错
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
//#include<fstream>
using namespace std;
int mesh[11][11];
struct Chess{
int x,y;
char ch;
};
struct Chess chess[8];
int N;
//传入黑将可能的坐标(4个)
bool iskill(int x,int y){
bool flag=1;
int step2[8]={-2,-2,2,2,-1,1,-1,1};//马8个方位的判断
int step[4]={-1,1,0,0};//蹩马脚判断
int j;
for(int i=0;i<N;i++){
if(mesh[chess[i].x][chess[i].y]!=chess[i].ch)continue;//当前棋子被黑将吃了,则继续
switch(chess[i].ch){
//红黑将在同一直线,且中间无子,则flag=0
case 'G':
if(chess[i].y==y){
for(j=x+1;j<chess[i].x;j++){
if(mesh[j][y]!=0)break;
}
if(j==chess[i].x)flag=0;
}
break;
//车将在同一直线,中间无子则flag=0
case 'R':
if(chess[i].y==y){
//将的上下2个方位
int x0=min(chess[i].x,x);
int x1=max(chess[i].x,x);
for(j=x0+1;j<x1;j++){
if(mesh[j][y]!=0)break;
}
if(j==x1)flag=0;
}
if(chess[i].x==x&&flag){
//将的左右2个方位
int y0=min(chess[i].y,y);
int y1=max(chess[i].y,y);
for(j=y0+1;j<y1;j++){
if(mesh[x][j]!=0)break;
}
if(j==y1)flag=0;
}
break;
//马可跳的方位如果存在黑将,则flag=0
case 'H':
for(j=0;j<=3;j++)
{//利用step[]判断是否可跳
if(mesh[chess[i].x+step[j]][chess[i].y+step[3-j]]==0)
{//判断马的落脚点是否为x,y
for(int k=j*2;k<=j*2+1;k++)
{
if(chess[i].x+step2[k]==x&&chess[i].y+step2[7-k]==y){flag=0;break;}
}
}
if(flag==0)break;
}
break;
case 'C':
int cnt=0;
if(chess[i].y==y){//判断是否在同y轴
int x0=min(chess[i].x,x);
int x1=max(chess[i].x,x);
for(j=x0+1;j<x1;j++){
if(mesh[j][y]!=0)cnt++;//计算2子中间的棋子数
}
if(cnt==1)flag=0;//中间仅有1个则不能
}
if(chess[i].x==x&&flag){
int y0=min(chess[i].y,y);
int y1=max(chess[i].y,y);
for(j=y0+1;j<y1;j++){
if(mesh[x][j]!=0)cnt++;
}
if(cnt==1)flag=0;
}
break;
}
if(flag==0)break;
}
return flag;
}
int main(){
char temp;
int step[4]={-1,1,0,0};
int x,y, cnt=1;
//fstream fin;
// fin.open("ans.txt",ios::out);
while(cin>>N>>x>>y && N&&x&&y){
//做棋盘
memset(mesh,0,sizeof(mesh));
mesh[x][y]='g';
for(int i=0;i<N;i++){
cin>>chess[i].ch>>chess[i].x>>chess[i].y;
mesh[chess[i].x][chess[i].y]=chess[i].ch;
}
bool flag=0;
//能直接将军对方则flag=1,输出NO
if(chess[0].y==y){
int j;
for(j=x+1;j<chess[0].x;j++){
if(mesh[j][y]!=0)break;
}
if(j==chess[0].x)flag=1;
}
//不能直接将军,判断黑将所有可走的位置
for(int i=0;i<=3;i++)
{
if(x+step[i]>=1&& x+step[i]<=3 && y+step[3-i]>=4&& y+step[3-i]<=6&&!flag)
{
mesh[x][y]=0;//棋盘改动,避免棋盘上多出一个棋子
temp=mesh[x+step[i]][y+step[3-i]];
mesh[x+step[i]][y+step[3-i]]='g';
//没被杀则为1
flag=iskill(x+step[i],y+step[3-i]);
mesh[x][y]='g';//恢复棋盘
mesh[x+step[i]][y+step[3-i]]=temp;
}
if(flag){
cout<<"NO\n";
// fin<<"NO\n";
break;
}
}
if(!flag){
cout<<"YES\n";
// fin<<"YES\n";
}
}
// fin.close();
return 0;
}
正方形UVa201
思路:暴力
#include<iostream>
#include<cstring>
using namespace std;
int H[10][10],V[10][10];
int n,m;
int judge(int len){
int num=0;
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
bool p=1;
for(int k=0;k<len;k++){
if(!H[i][j+k] || !V[i+k][j] || !H[i+len][j+k] || !V[i+k][j+len])
{
p=0;break;
}
}
if(p)num++;
}
}
return num;
}
int main(){
int cnt=1;
while(cin>>n>>m&&n&&m){
char ch;
int r,c;
memset(H,0,sizeof(H));
memset(V,0,sizeof(V));
//读入
for(int i=1;i<=m;i++){
cin>>ch>>r>>c;
if(ch=='H')H[r][c]=1;
if(ch=='V')V[c][r]=1;//这里是个坑点,H跟V定义的方向不一样
}
//计算
int ans[10],flag=1,len;
memset(ans, 0 ,sizeof (ans));
for(len=1;len<=n;len++){
ans[len]=judge(len);
if(ans[len]!=0)flag=0;
}
//输出
cout<<"Problem #"<<cnt++<<endl<<endl;
if(flag)cout<<"No completed squares can be found."<<endl;
else
for(int i=1;i<=n;i++){
if(ans[i]!=0)cout<<ans[i]<<" square (s) of size "<<i<<endl;
}
cout<<endl<<"***********************************"<<endl;
}
}
黑白棋UVa220