Ultraviolet A 519 Puzzle (II)

Source: Internet
Author: User

UVA_519

At first, the raw tracing and timeout occurred. Later, I thought of some pre-judgment, but it still timed out. After reading a post posted on the Forum, I said that the pre-judgment could not be saving, so I almost gave up the idea of continuing to think carefully about pre-judgment.

Then go to W. c. I thought of a more detailed pre-judgment, and then continued to think about it based on this idea, so I got more detailed pre-judgment, and finally AC, I feel that careful pre-judgment is a strong pruning.

During the pre-judgment, I mainly considered the following points:

① Globally, I/O numbers should be equal.

② The number of all F should be 2 * (M + N), but this is not detailed enough. It is not difficult for us to think about it carefully, the numbers of F in top and bottom are M, and the numbers of F in left and right are N, respectively.

③ Inspired by the separation of the four sides in the discussion ②, we can also think that the total IO numbers of left and right on the top and bottom sides should be equal. Likewise, the total I/O count of top and bottom on the left and right edges should be equal.

④ According to the size of the puzzle, the number of F on the corner should be limited. The limit may be called limitk. For example, if N and M are both 1, then the angle should have four F. If N and M have only one and only one is 1, then the angle should have three F, if N and M are not 1, the angle should have 2 F. The above analysis gives us two inspirations. First, F on the corner is the most. Therefore, if the number of F in a piece exceeds limitk, it is clear that there is no solution. Second, if the number of angles where the number of F is limited does not match the corresponding value, there is no solution. I didn't elaborate on every corner in my program. I just checked whether each piece of puzzle had a limit of F, in fact, you can also further refine whether each angle has only one according to the position of F.

#include<stdio.h>
#include<string.h>
#define MAXD 40
#define MAXN 10
int N, M, T, top[MAXD], right[MAXD], bottom[MAXD], left[MAXD];
int D[MAXN][MAXN], R[MAXN][MAXN], A[MAXD];
char b[MAXN], *str = "IFO";
void init()
{
int i, j, k;
T = N * M;
for(i = 0; i < T; i ++)
{
scanf("%s", b);
top[i] = strchr(str, b[0]) - str - 1;
right[i] = strchr(str, b[1]) - str - 1;
bottom[i] = strchr(str, b[2]) - str - 1;
left[i] = strchr(str, b[3]) - str - 1;
}
}
int place(int cur, int x, int y)
{
if(x == 0 && top[cur] != 0)
return 0;
if(x != 0 && top[cur] + D[x - 1][y] != 0)
return 0;
if(y == M - 1 && right[cur] != 0)
return 0;
if(y != M - 1 && right[cur] == 0)
return 0;
if(x == N - 1 && bottom[cur] != 0)
return 0;
if(x != N - 1 && bottom[cur] == 0)
return 0;
if(y == 0 && left[cur] != 0)
return 0;
if(y != 0 && left[cur] + R[x][y - 1] != 0)
return 0;
return 1;
}
int dfs(int x, int y)
{
int i, j, k;
if(y == M)
++ x, y = 0;
if(x == N)
return 1;
for(i = 0; i < T; i ++)
if(!A[i] && place(i, x, y))
{
A[i] = 1;
D[x][y] = bottom[i], R[x][y] = right[i];
if(dfs(x, y + 1))
return 1;
A[i] = 0;
}
return 0;
}
int check()
{
int i, j, k, limitk, upcnt, downcnt, leftcnt, rightcnt;
int iototal, ioup, iodown, ioleft, ioright, num;
iototal = ioup = iodown = ioleft = ioright = 0;
upcnt = downcnt = leftcnt = rightcnt = num = 0;
if(N == 1 && M == 1)
limitk = 4;
else if(N == 1 || M == 1)
limitk = 3;
else
limitk = 2;
for(i = 0; i < T; i ++)
{
k = 0;
if(top[i] == 0)
++ upcnt, ++ k, ioup = ioup + (left[i] + right[i]);
if(right[i] == 0)
++ rightcnt, ++ k, ioright = ioright + (top[i] + bottom[i]);
if(bottom[i] == 0)
++ downcnt, ++ k, iodown = iodown + (left[i] + right[i]);
if(left[i] == 0)
++ leftcnt, ++ k, ioleft = ioleft + (top[i] + bottom[i]);
if(k > limitk)
return 0;
if(k == limitk)
++ num;
iototal = iototal + (top[i] + right[i] + bottom[i] + left[i]);
}
if(limitk == 2 && num != 4)
return 0;
if(limitk == 3 && num != 2)
return 0;
if(limitk == 4 && num != 1)
return 0;
if(upcnt != M || downcnt != M || leftcnt != N || rightcnt != N)
return 0;
if(iototal != 0 || ioup != 0 || ioright != 0 || iodown != 0 || ioleft != 0)
return 0;
return 1;
}
void solve()
{
if(!check())
{
printf("NO\n");
return ;
}
memset(A, 0, sizeof(A));
if(dfs(0, 0))
printf("YES\n");
else
printf("NO\n");
}
int main()
{
for(;;)
{
scanf("%d%d", &N, &M);
if(!N && !M)
break;
init();
solve();
}
return 0;
}


Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.