http://acm.timus.ru/problem.aspx?space=1&num=1155
原來的題目描述:
1155. Troubleduons
Memory Limit: 16 MB
“O, Lord! Those physicists on the Earth have discovered a new elementary particle!”
“No problem, we’ll add another parameter to the General Equation of the Universe.”
Input
Output
Samples
input | output |
---|---|
1 0 1 0 3 1 0 0 |
EF- EA- AD+ AE- DC- |
0 1 0 1 2 3 2 2 |
IMPOSSIBLE |
All submissions (1804) All accepted submissions (689) Solutions rating (629)
題目大意描述:
一個正方體,各個頂點有一個初始值,(從0號頂點到7號頂點依次輸入數值)。相鄰頂點上的數值可以同增或同減。
問能不能通過同增或同減,使所有數變成0。若不能,輸出“IMPOSSIBLE”,若能,則按上面的樣例輸出消去各個數的步驟。
解題:
我會告訴你這個題目是劉汝佳黑書上歸類於數論的題目麼?
我會告訴你要做這個題目,得到某國外網站註冊好不麻煩的麼?
我會告訴你這是個二分圖的題目麼?
二分圖:
這是個二分圖 !
代碼:
#include <iostream>
#include <cstdlib>
#include <cstdio>
#include <cstring>
char adjj[100][10] = {"AB", "BC", "CD", "AD", "AE", "BF", "CG", "DH", "EF", "GF", "HG", "EH"};
int opp[10] = {6, 7, 4, 5, 2, 3, 0, 1};
int a[10];
int adj[10][10];
#define INF 99999999
using namespace std;
#define N 8
void build()
{
memset(adj, 0, sizeof (adj));
for (int j= 0; j < 12; j++)
adj[ adjj[j][0] - 65] [ adjj[j][1] - 65] = adj[ adjj[j][1] - 65] [ adjj[j][0] - 65] =1;
}
bool valid()
{
if (a[0] + a[2] + a[5] + a[7] == a[1] + a[3] + a[4] + a[6])
return true;
else
return false;
}
void solve()
{
bool flag;
int max, min, o, index;
max = -INF;
for (int j = 0; j < N; j++)
if (a[j] > max)
{
max = a[j];
index = j;
}
for (int j = 0; j< N; j++)
if (adj[index] [j])
{
for (int k = 0; k< N; k++)
if (adj[j][k])
{
min = a[j] < a[k] ? a[j] : a[k];
a[j] -= min;
a[k] -= min;
for (int p = 0; p < min; p++)
printf("%c%c-\n", (char)(j + 65), (char)(k + 65));
}
min = a[index] < a[j] ? a[index] : a[j];
a[index] -= min;
a[j] -= min;
for (int p = 0; p< min; p++)
printf("%c%c-\n", (char)(index + 65), (char)(j + 65));
}
o = opp[index];
for (int j = 0; j< N; j++)
if (adj[o] [j])
{
for (int k = 0; k< N; k++)
if (adj[j][k])
{
min = a[j] < a[k] ? a[j] : a[k];
a[j] -= min;
a[k] -= min;
for (int p = 0; p < min; p++)
printf("%c%c-\n", (char)(j + 65), (char)(k + 65));
}
min = a[o] < a[j] ? a[o] : a[j];
a[o] -= min;
a[j] -= min;
for (int p = 0; p < min; p++)
printf("%c%c-\n", (char)(j + 65), (char)(o + 65));
}
flag = true;
while (flag)
{
flag = false;
for (int j = 0; j<N; j++)
if (a[j] != 0)
{
flag = true;
// for (int k = 0; k<N; k++)
// {
// if (adj[j][k] && a[k] > 0)
// {
// min = a[j] < a[k] ? a[j] : a[k];
//
// a[j] -= min;
// a[k] -= min;
// for (int p = 0; p<min; p++)
// printf("%c%c-\n", (char)(j+65), (char)(k+65));
// }
// }
o = opp[j];
for (int k = 0; k< N; k++)
if (adj[j][k])
for (int l=0; l<N; l++)
if (adj[k][l] && adj[l][o])
{
min = a[j] < a[o] ? a[j] : a[o];
a[j] -= min;
a[o] -= min;
for (int p=0; p<min; p++)
printf("%c%c+\n%c%c-\n%c%c-\n", (char)(l+65), (char)(k+65),
(char)(o+65),(char)(l+65),
(char)(j+65),(char)(k+65));
}
}
}
}
int main()
{
for (int j= 0; j <N; j++)
cin >> a[j];
if ( ! valid())
cout << "IMPOSSIBLE" << endl;
else
{
build();
solve();
}
return 0;
}
寫的不是很有條例 。