The Clocks
题目大意 现有9个钟,有以下移动方案。注:一次移动会移动15分钟。
移动方法 | 受影响的时钟 |
1 | ABDE |
2 | ABC |
3 | BCEF |
4 | ADG |
5 | BDEFH |
6 | CFI |
7 | DEGH |
8 | GHI |
9 | EFHI |
给你9个钟的时间,是指向3/6/9/12点钟方向的,问你要怎么使用方案才能使所有钟指向12点,输出方案(输出组合起来数字小的那一组)
实现流程
刚看到这道题,没多想,以为和之前一样是暴力题。呵呵呵,dg深搜。。。时间超限。我看了一下,额。。。暴力Dg会无限执行下去。我只好想优化。想啊想,蒙了个逼。怎么做啊?!幸好,HZH(回文串?!)来了,啊哈,思路出来了!9重循环!(这不爆才怪呢)我发现,每个方案连续执行4次就会回到原来的样子,即4次一循环。所以,只要9重枚举第i种方案的出现次数就可以了。完全不用担心时间,你程序打得再丑也不会爆。里面再判断一下方案大小,最后输出答案就行了。这样我里面虽然用了10重循环(说好的9重呢),但时间复杂度也不过是O(262144ans)(ans为方案的个数)
如需代码,请到下方
代码实现
#include<cstdio>
using namespace std;
int a[10],ans,a1,b1,c,d,e,f,g,h,i,b[10],o,s[1000000],x[1000000],max;
bool bz;
int main()
{
ans=2147483647;
scanf("%d%d%d",&a[1],&a[2],&a[3]);
scanf("%d%d%d",&a[4],&a[5],&a[6]);
scanf("%d%d%d",&a[7],&a[8],&a[9]);
for (i=1;i<=9;i++) a[i]%=12;
for (a1=0;a1<=3;a1++)
{
for (b1=0;b1<=3;b1++)
{
for (c=0;c<=3;c++)
{
for (d=0;d<=3;d++)
{
for (e=0;e<=3;e++)
{
for (f=0;f<=3;f++)
{
for (g=0;g<=3;g++)
{
for (h=0;h<=3;h++)
{
for (i=0;i<=3;i++)
{
b[1]=(a[1]+3*(a1+b1+d))% 12;
b[2]=(a[2]+3*(a1+b1+c+e))%12;
b[3]=(a[3]+3*(b1+c+f))%12;
b[4]=(a[4]+3*(a1+d+e+g))%12;
b[5]=(a[5]+3*(a1+c+e+g+i))%12;
b[6]=(a[6]+3*(c+e+f+i))%12;
b[7]=(a[7]+3*(d+g+h))%12;
b[8]=(a[8]+3*(e+g+h+i))%12;
b[9]=(a[9]+3*(f+h+i))%12;
if (b[1]+b[2]+b[3]+b[4]+b[5]+b[6]+b[7]+b[8]+b[9]==0)
{
if (a1+b1+c+d+e+f+g+h+i<=ans)
{
max=ans;
ans=a1+b1+c+d+e+f+g+h+i;
for (o=1;o<=ans;o++)
{
if (o<=a1) s[o]=1; else
if (o<=a1+b1) s[o]=2; else
if (o<=a1+b1+c) s[o]=3; else
if (o<=a1+b1+c+d) s[o]=4; else
if (o<=a1+b1+c+d+e) s[o]=5; else
if (o<=a1+b1+c+d+e+f) s[o]=6; else
if (o<=a1+b1+c+d+e+f+g) s[o]=7; else
if (o<=a1+b1+c+d+e+f+g+h) s[o]=8; else
if (o<=a1+b1+c+d+e+f+g+h+i) s[o]=9;
}
if (max=ans)
{
bz=true;
for (o=1;o<=ans;o++)
{
if (s[o]>x[o])
{
bz=false;
break;
}
}
if (bz=true)
for (o=1;o<=ans;o++)
{
x[o]=s[o];
}
}
}
}
}
}
}
}
}
}
}
}
}
for (i=1;i<=ans;i++)
printf("%d ",x[i]);
}
如果自己说什麽都做不到而什麽都不去做的话,那就更是什麽都做不到,什麽都不会改变,什麽都不会结束.