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");
}
}
}