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]);
}

posted @ 2018-01-31 21:35  Sport_River  阅读(140)  评论(0编辑  收藏  举报