poj 1574 The Triangle Game
地址:http://acm.pku.edu.cn/JudgeOnline/problem?id=1574
题目分析:
给你六个三角形,并且给你三角形各条边的权值,问是否能将这三角形拼凑成一个六边形,如果可以的话,输出最小的轮廓周长。
只要题目中的图再一看,就可以很清晰的理解题目了。
具体分析:
其实不难,我们用一个six[]数组记录六边形的轮廓周长,如果当前三角形中与前一条边相匹配的编号是j 的话,那么它贡献的轮廓的编号就是(j + 1)%3, 要被匹配的边就变成了(j + 2 ) %3....DFS就可以完成了。
AC代码:
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<cstdlib>
#include<cmath>
#include<queue>
#include<vector>
#include<stack>
using namespace std;
int Tri[8][3],six[8],vis[8];
int ans,First;
void DFS(int pos, int index ,int cnt)
{
//cout << "Ok" << endl;
if(cnt == 6)
{
int sum = 0;
for(int i = 0 ;i < cnt ;i++)
{
sum += six[i];
//cout << six[i] << " ";
}
//cout << sum << endl;
if(sum > ans)
ans = sum;
return ;
}
for(int i = 0 ;i < 6 ;i++ )
{
for(int j = 0 ;j < 3 ;j++)
if(!vis[i] && Tri[i][j] == Tri[pos][index])
{
if(cnt < 5)
{
vis[i] = 1;
six[cnt ] = Tri[i][(j + 1)%3];
/*
if( cnt == 1 )
printf("i is %d ,j is %d ,x is %d val is %d\n", i ,j ,(j+1)%3, six[cnt + 1]);
*/
DFS(i, (j + 2)%3, cnt + 1);
vis[i] = 0;
}
else if(cnt == 5)
{
if(Tri[i][(j + 2) % 3 ] == First)
{
vis[i] = 1;
six[cnt ] = Tri[i][(j + 1) %3];
DFS(i,(j + 2)%3, cnt + 1);
vis[i] = 0;
}
}
}
}
return ;
}
int main()
{
char ch;
while(1)
{
ans = -1;
memset(vis, 0, sizeof(vis));
for(int i = 0 ;i < 6 ;i++)
cin >> Tri[i][0] >> Tri[i][1] >> Tri[i][2];
cin >> ch;
for(int i = 0 ;i < 6 ;i++)
{
for(int j = 0 ;j < 3 ;j++)
if(!vis[i] )
{
// cout << "Ok1" << endl;
First = Tri[i][j];
vis[i] = 1;
six[0] = Tri[i][(j + 1) %3];
DFS(i,(j + 2)%3 ,1);
vis[i] = 0;
}
}
//cout << "OK" << endl;
if(ans == -1)
cout << "none" << endl;
else
cout << ans << endl;
if(ch == '$')
break;
}
return 0;
}