题目:有9个时钟,排成一个3*3的矩阵。
|-------| |-------| |-------| | | | | | | | |---O | |---O | | O | | | | | | | |-------| |-------| |-------| A B C |-------| |-------| |-------| | | | | | | | O | | O | | O | | | | | | | | | | |-------| |-------| |-------| D E F |-------| |-------| |-------| | | | | | | | O | | O---| | O | | | | | | | | | |-------| |-------| |-------| G H I (图 1)
现在需要用最少的移动,将9个时钟的指针都拨到12点的位置。共允许有9种不同的移动。如下表所示,每个移动会将若干个时钟的指针沿顺时针方向拨动90度。
移动 影响的时钟 1 ABDE 2 ABC 3 BCEF 4 ADG 5 BDEFH 6 CFI 7 DEGH 8 GHI 9 EFHI
3 3 0 2 2 2 2 1 2
4 5 8 9
i)算法思路:因为操作1、2、3和操作4、5、6就能确定时钟A,B,C的状态,所以可以根据枚举操作1、2、3的组合来确定4、5、6操作如何进行,类似确定7、8、9操作的执行
#include<iostream>
#include<algorithm>
#include<cstring>
#include<vector>
using namespace std;
#include<algorithm>
#include<cstring>
#include<vector>
using namespace std;
void operate(int operations[10][10],int clock2[10],int opNum,int opCount)
{
for(int i = 1;i <= 9;i ++)
{
clock2[i] += operations[opNum][i]*opCount;
clock2[i] %= 4;
}
}
{
for(int i = 1;i <= 9;i ++)
{
clock2[i] += operations[opNum][i]*opCount;
clock2[i] %= 4;
}
}
int main()
{
int clock[10];
int clock2[10];
int minTimes = 28;
int opTimes[10];
int minOpTimes[10];
int operations[10][10] =
{
{0},
{0,1,1,0,1,1,0,0,0,0},
{0,1,1,1,0,0,0,0,0,0},
{0,0,1,1,0,1,1,0,0,0},
{0,1,0,0,1,0,0,1,0,0},
{0,0,1,0,1,1,1,0,1,0},
{0,0,0,1,0,0,1,0,0,1},
{0,0,0,0,1,1,0,1,1,0},
{0,0,0,0,0,0,0,1,1,1},
{0,0,0,0,0,1,1,0,1,1},
};
//保存1,2,3的操作的所有组合方式
int move123[64][3];//每种操作有0,1,2,3共4种选择,所以共有4^3中组合方式
for(int i = 0;i < 64;i ++)
{
int num = i;
for(int j = 2;j >= 0;j --) //把num换成4进制数
{
move123[i][j] = num % 4;
num /= 4;
}
}
for(int x = 1;x <= 9;x ++)
cin >> clock[x];
for(int i = 0;i < 64;i ++)
{
memcpy(clock2,clock,sizeof(int) * 10);
memset(opTimes,0,sizeof(int) * 10);
for(int j = 1;j <= 3;j ++)
{
opTimes[j] = move123[i][3-j]; //跟前面求1,2,3所有的操作呼应 ,使执行的次数从小到大枚举
operate(operations,clock2,j,opTimes[j]);
}
for(int j = 4;j <= 6;j ++)
{
opTimes[j] = (4 - clock2[j-3]) % 4;
operate(operations,clock2,j,opTimes[j]);
}
opTimes[7] = (4 - clock2[4]) % 4;
operate(operations,clock2,7,opTimes[7]);
opTimes[9] = (4 - clock2[6]) % 4;
operate(operations,clock2,9,opTimes[9]);
if(clock2[5] == 0 && clock2[7] == clock2[8] && clock2[8] == clock2[9]) //判断E是否为零,还有最后三是否相等
{
opTimes[8] = (4 - clock2[7]) % 4;
int tem = 0;
for(int i = 1;i <= 9;i ++)
tem += opTimes[i];
if(tem < minTimes)
{
minTimes = tem;
memcpy(minOpTimes,opTimes,sizeof(int) * 10);
}
}
}
vector <int> result;
for(int i = 1;i <= 9;i ++)
{
while(minOpTimes[i] --)
{
result.push_back(i);
}
}
sort(result.begin(),result.end());
vector<int>::iterator it;
for(it = result.begin();it != result.end();it ++)
cout << *it <<' ';
cout << endl;
return 0;
}
{
int clock[10];
int clock2[10];
int minTimes = 28;
int opTimes[10];
int minOpTimes[10];
int operations[10][10] =
{
{0},
{0,1,1,0,1,1,0,0,0,0},
{0,1,1,1,0,0,0,0,0,0},
{0,0,1,1,0,1,1,0,0,0},
{0,1,0,0,1,0,0,1,0,0},
{0,0,1,0,1,1,1,0,1,0},
{0,0,0,1,0,0,1,0,0,1},
{0,0,0,0,1,1,0,1,1,0},
{0,0,0,0,0,0,0,1,1,1},
{0,0,0,0,0,1,1,0,1,1},
};
//保存1,2,3的操作的所有组合方式
int move123[64][3];//每种操作有0,1,2,3共4种选择,所以共有4^3中组合方式
for(int i = 0;i < 64;i ++)
{
int num = i;
for(int j = 2;j >= 0;j --) //把num换成4进制数
{
move123[i][j] = num % 4;
num /= 4;
}
}
for(int x = 1;x <= 9;x ++)
cin >> clock[x];
for(int i = 0;i < 64;i ++)
{
memcpy(clock2,clock,sizeof(int) * 10);
memset(opTimes,0,sizeof(int) * 10);
for(int j = 1;j <= 3;j ++)
{
opTimes[j] = move123[i][3-j]; //跟前面求1,2,3所有的操作呼应 ,使执行的次数从小到大枚举
operate(operations,clock2,j,opTimes[j]);
}
for(int j = 4;j <= 6;j ++)
{
opTimes[j] = (4 - clock2[j-3]) % 4;
operate(operations,clock2,j,opTimes[j]);
}
opTimes[7] = (4 - clock2[4]) % 4;
operate(operations,clock2,7,opTimes[7]);
opTimes[9] = (4 - clock2[6]) % 4;
operate(operations,clock2,9,opTimes[9]);
if(clock2[5] == 0 && clock2[7] == clock2[8] && clock2[8] == clock2[9]) //判断E是否为零,还有最后三是否相等
{
opTimes[8] = (4 - clock2[7]) % 4;
int tem = 0;
for(int i = 1;i <= 9;i ++)
tem += opTimes[i];
if(tem < minTimes)
{
minTimes = tem;
memcpy(minOpTimes,opTimes,sizeof(int) * 10);
}
}
}
vector <int> result;
for(int i = 1;i <= 9;i ++)
{
while(minOpTimes[i] --)
{
result.push_back(i);
}
}
sort(result.begin(),result.end());
vector<int>::iterator it;
for(it = result.begin();it != result.end();it ++)
cout << *it <<' ';
cout << endl;
return 0;
}
ii)很遗憾没能看懂
#define TABLE_LEN 5
#include<stdio.h>
const int table[10][TABLE_LEN]=
{{},{1,2,4,5},{1,2,3},{2,3,5,6},
{1,4,7},{2,4,5,6,8},{3,6,9},
{4,5,7,8},{7,8,9},{5,6,8,9}};
{{},{1,2,4,5},{1,2,3},{2,3,5,6},
{1,4,7},{2,4,5,6,8},{3,6,9},
{4,5,7,8},{7,8,9},{5,6,8,9}};
int state[10];
int times[10],min=0x7FFFFFFF,ans_times[10];
bool isFirst=true;
int times[10],min=0x7FFFFFFF,ans_times[10];
bool isFirst=true;
void deal(int k,int total)
{
if (k==10)
{
for (int i=1;i<=9;i++)
if (state[i]&3)
return;
if (total<min)
{
min=total;
for (int i=1;i<=9;i++)
ans_times[i]=times[i];
}
return;
}
for (times[k]=0;times[k]<4;times[k]++) //每个操作最多执行3次
{
for (int i=0;i<TABLE_LEN;i++)
state[table[k][i]]+=times[k];
deal(k+1,total+times[k]);
for (int i=0;i<TABLE_LEN;i++)
state[table[k][i]]-=times[k];
}
return;
}
{
if (k==10)
{
for (int i=1;i<=9;i++)
if (state[i]&3)
return;
if (total<min)
{
min=total;
for (int i=1;i<=9;i++)
ans_times[i]=times[i];
}
return;
}
for (times[k]=0;times[k]<4;times[k]++) //每个操作最多执行3次
{
for (int i=0;i<TABLE_LEN;i++)
state[table[k][i]]+=times[k];
deal(k+1,total+times[k]);
for (int i=0;i<TABLE_LEN;i++)
state[table[k][i]]-=times[k];
}
return;
}
int main()
{
for (int i=1;i<=9;i++)
scanf("%d",&state[i]);
deal(1,0);
for (int i=1;i<=9;i++)
for (int j=0;j<ans_times[i];j++)
{
if (isFirst)
isFirst=false;
else
printf(" ");
printf("%d",i);
}
printf("\n");
return 0;
}
{
for (int i=1;i<=9;i++)
scanf("%d",&state[i]);
deal(1,0);
for (int i=1;i<=9;i++)
for (int j=0;j<ans_times[i];j++)
{
if (isFirst)
isFirst=false;
else
printf(" ");
printf("%d",i);
}
printf("\n");
return 0;
}