題目:如圖的19個小六邊形(對邊數字相同)拼成的大六邊形,在3行數字鐘分別選擇三條直線的值,
使得所有19個六邊形不同(一共有27種選擇),求出直線上數字加和的最大值(相同才有值)。
分析:搜索,枚舉。這裡我是打表計算的。
首先,使得直線上的數字相同時才能取得最大值否則損失了這條直線的值;
然後,利用一個程序打表計算所有情況,去掉有重複的小六邊形情況;
發現,只有三種選擇情況(三個數字的取值次數:5, 6, 8|5, 7, 7|5, 7, 7);
最後,編程枚舉三種排列方式,找到最大值即可。
說明:還有三道題╮(╯▽╰)╭。
#include <algorithm>
#include <iostream>
#include <cstdlib>
#include <cstring>
#include <cstdio>
using namespace std;
int value[3][3];
int list[3][9] = {
5, 6, 8, 5, 7, 7, 5, 7, 7,
5, 7, 7, 5, 6, 8, 5, 7, 7,
5, 7, 7, 5, 7, 7, 5, 6, 8,
};
int main()
{
int n;
while (~scanf("%d",&n))
for (int t = 1; t <= n; ++ t) {
for (int i = 0; i < 3; ++ i) {
for (int j = 0; j < 3; ++ j) {
scanf("%d",&value[i][j]);
}
}
for (int i = 0; i < 3; ++ i) {
sort(value[i], value[i]+3);
}
int max = 0;
for (int i = 0; i < 3; ++ i) {
int sum = 0;
for (int j = 0; j < 3; ++ j) {
for (int k = 0; k < 3; ++ k) {
sum += list[i][j*3+k] * value[j][k];
}
}
if (max < sum) {
max = sum;
}
}
printf("Test #%d\n%d\n\n",t,max);
}
return 0;
}
打表程序:
#include <algorithm>
#include <iostream>
#include <cstdlib>
#include <cstring>
#include <cstdio>
#include <string>
#include <set>
using namespace std;
int map[3][3][3];
int size[5] = {3, 4, 5, 4, 3};
int main()
{
set <string>ans;
int a[5], b[5], c[5], total = 0;
for ( a[0] = 0; a[0] < 3; ++ a[0])
for ( a[1] = 0; a[1] < 3; ++ a[1])
for ( a[2] = 0; a[2] < 3; ++ a[2])
for ( a[3] = 0; a[3] < 3; ++ a[3])
for ( a[4] = 0; a[4] < 3; ++ a[4])
for ( b[0] = 0; b[0] < 3; ++ b[0])
for ( b[1] = 0; b[1] < 3; ++ b[1])
for ( b[2] = 0; b[2] < 3; ++ b[2])
for ( b[3] = 0; b[3] < 3; ++ b[3])
for ( b[4] = 0; b[4] < 3; ++ b[4])
for ( c[0] = 0; c[0] < 3; ++ c[0])
for ( c[1] = 0; c[1] < 3; ++ c[1])
for ( c[2] = 0; c[2] < 3; ++ c[2])
for ( c[3] = 0; c[3] < 3; ++ c[3])
for ( c[4] = 0; c[4] < 3; ++ c[4]) {
for (int i = 0; i < 3; ++ i)
for (int j = 0; j < 3; ++ j)
for (int k = 0; k < 3; ++ k)
map[i][j][k] = 0;
//第一列
if (map[a[0]][b[0]][c[2]]) continue;
map[a[0]][b[0]][c[2]] = 1;
if (map[a[0]][b[1]][c[3]]) continue;
map[a[0]][b[1]][c[3]] = 1;
if (map[a[0]][b[2]][c[4]]) continue;
map[a[0]][b[2]][c[4]] = 1;
//第二列
if (map[a[1]][b[0]][c[1]]) continue;
map[a[1]][b[0]][c[1]] = 1;
if (map[a[1]][b[1]][c[2]]) continue;
map[a[1]][b[1]][c[2]] = 1;
if (map[a[1]][b[2]][c[3]]) continue;
map[a[1]][b[2]][c[3]] = 1;
if (map[a[1]][b[3]][c[4]]) continue;
map[a[1]][b[3]][c[4]] = 1;
//第三列
if (map[a[2]][b[0]][c[0]]) continue;
map[a[2]][b[0]][c[0]] = 1;
if (map[a[2]][b[1]][c[1]]) continue;
map[a[2]][b[1]][c[1]] = 1;
if (map[a[2]][b[2]][c[2]]) continue;
map[a[2]][b[2]][c[2]] = 1;
if (map[a[2]][b[3]][c[3]]) continue;
map[a[2]][b[3]][c[3]] = 1;
if (map[a[2]][b[4]][c[4]]) continue;
map[a[2]][b[4]][c[4]] = 1;
//第四列
if (map[a[3]][b[1]][c[0]]) continue;
map[a[3]][b[1]][c[0]] = 1;
if (map[a[3]][b[2]][c[1]]) continue;
map[a[3]][b[2]][c[1]] = 1;
if (map[a[3]][b[3]][c[2]]) continue;
map[a[3]][b[3]][c[2]] = 1;
if (map[a[3]][b[4]][c[3]]) continue;
map[a[3]][b[4]][c[3]] = 1;
//第五列
if (map[a[4]][b[2]][c[0]]) continue;
map[a[4]][b[2]][c[0]] = 1;
if (map[a[4]][b[3]][c[1]]) continue;
map[a[4]][b[3]][c[1]] = 1;
if (map[a[4]][b[4]][c[2]]) continue;
map[a[4]][b[4]][c[2]] = 1;
int count[3][3];
for (int i = 0; i < 3; ++ i)
for (int j = 0; j < 3; ++ j)
count[i][j] = 0;
//printf(" a:");
for (int i = 0; i < 5; ++ i) {
printf("%d, ",a[i]);
count[0][a[i]] += size[i];
}
sort(count[0], count[0]+3);
//printf(" b:");
for (int j = 0; j < 5; ++ j) {
printf("%d, ",b[j]);
count[1][b[j]] += size[j];
}
sort(count[1], count[1]+3);
//printf(" c:");
for (int k = 0; k < 5; ++ k) {
printf("%d, ",c[k]);
count[2][c[k]] += size[k];
}
sort(count[2], count[2]+3);
printf(" : ");
string str = "000000000";
for (int i = 0; i < 3; ++ i)
for (int j = 0; j < 3; ++ j) {
printf("%d ",count[i][j]);
str[i*3+j] += count[i][j];
}
puts("");
total ++;
if (ans.count(str) > 0) {
;
}else {
ans.insert(str);
}
}
printf("total = %d\n",total);
// 输出取值的组合
set<string>::reverse_iterator rit;
for (rit = ans.rbegin(); rit != ans.rend(); ++ rit) {
cout << *rit << endl;
}
getchar();
return 0;
}