http://acm.timus.ru/problem.aspx?space=1&num=1155
原来的题目描述:
1155. Troubleduons
Time Limit: 0.5 second
Memory Limit: 16 MB
Memory Limit: 16 MB
Archangel of the Science is reporting:
“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.”
“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.”
As physics develops and moves on, scientists find more and more strange elementary particles, whose properties are more than unknown. You may have heard about muons, gluons and other strange particles. Recently scientists have found new elementary particles called troubleduons. These particles are called this way because scientists can create or annihilate them only in couples. Besides, troubleduons cause trouble to scientists, and that’s why the latter want to get rid of them. You should help scientists get rid of troubleduons.
Experimental set consists of eight cameras, situated in the vertices of a cube. Cameras are named as A, B, C, …, H. It is possible to generate or annihilate two troubleduons in neighbouring cameras. You should automate the process of removing troubleduons.
Input
The only line contain eight integers ranging from 0 to 100, representing number of troubleduons in each camera of experimental set.
Output
Output sequence of actions leading to annihilating all troubleduons or “IMPOSSIBLE”, if you cannot do it. Actions should be described one after another, each in a separate line, in the following way: name of the first camera, name of the second camera (it should be a neighborough to the first one), “+” if you create troubleduons, “-” if you destroy them. Number of actions in the sequence should not exceed 1000.
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 |
Problem Source: Ural Collegiate Programming Contest, April 2001, Perm, English Round
Difficulty: 504
Printable version
Submit solution
Discuss (11)
All submissions (1804) All accepted submissions (689) Solutions rating (629)
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;
}
写的不是很有条例 。