HDU 1518

Square

 

Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 7173    Accepted Submission(s): 2332

 

 

 

Problem Description

 

 

Given a set of sticks of various lengths, is it possible to join them end-to-end to form a square?
 

 

Input

 

The first line of input contains N, the number of test cases. Each test case begins with an integer 4 <= M <= 20, the number of sticks. M integers follow; each gives the length of a stick - an integer between 1 and 10,000.
 

 

Output

 

For each case, output a line containing "yes" if is is possible to form a square; otherwise output "no".
 

 

Sample Input

 

 
3 4 1 1 1 1 5 10 20 30 40 50 8 1 7 2 6 4 4 3 5
 

 

Sample Output

 

 
yes no yes
 
 
老实说,自己写的话绝对超时到一塌糊涂,找的这份代码感觉剪枝已经做得相当好了,最后过时859MS左右。。。
 
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
int n,m,t;
char map[10][10];
int mark[10][10];
int x1,y1,x2,y2;
int mov[4][2]={{0,1},{0,-1},{1,0},{-1,0}};
int flag;
void dfs(int x,int y,int step)
{
 int i,j;
 int tempx,tempy;
 if(x==x2&&y==y2){
  if(step==0){
   flag=1;
  }
  return;
 }
 if(flag){
  return;
 }
 int dis=abs(x-x2)+abs(y-y2);
 if(step-dis<0||(step-dis)%2!=0){
  return;
 }
 for(i=0;i<4;i++){
  tempx=x+mov[i][0];
  tempy=y+mov[i][1];
  if(tempx>=1&&tempx<=n&&tempy>=1&&tempy<=m&&!mark[tempx][tempy]&&map[tempx][tempy]!='X'){
   mark[tempx][tempy]=1;
   dfs(tempx,tempy,step-1);
   mark[tempx][tempy]=0;
  }
 }
}
main()
{
 while(scanf("%d %d %d%*c",&n,&m,&t),n+m+t){
  memset(map,0,sizeof(map));
  memset(mark,0,sizeof(mark));
  int i,j;
  int number=0;
  for(i=1;i<=n;i++){
   for(j=1;j<=m;j++){
    scanf("%c",&map[i][j]);
    if(map[i][j]=='S'){
     x1=i;
     y1=j;
    }
    if(map[i][j]=='D'){
     number++;
     x2=i;
     y2=j;
    }
    if(map[i][j]=='.'){
     number++;
    }
   }
   scanf("%*c");
  }
  if(number<t){
   printf("NO\n");
   continue;
  }
  flag=0;
  mark[x1][y1]=1;
  dfs(x1,y1,t);
  if(!flag){
   printf("NO\n");
  }
  else{
   printf("YES\n");
  }
 }
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值