题意:有5个不透明圆盘,有各自的转速,每个圆盘上有W个缺口(1<=W<=5),给定缺口的位置和大小。将这5个圆盘串到一根棍子上,0度对齐,求多少秒后一束光能穿过这5个圆盘?
解题思路:
- 简单模拟一下就行。对每个圆盘,根据转速确定多少秒后会回到初始状态,求这些时间的最小共倍数。只需要模拟到这个最小共倍数就行。为了简单,可以模拟到359秒,因为360秒后每个圆盘一定同时回到初始状态。
- 对每个模拟的状态,确定会不会有缺口有重叠,则光可以穿过,得到结果。
- 确定缺口重叠的方法:用一个数组wedges[i][j][k]保存这些缺口,代表第i个圆盘的第j个缺口的角度。wedges[i][j][0]为缺口起点,wedges[i][j][1]为缺口终点。因为每个圆盘有若干个缺口,所以这里有一个组合的问题。
- 对特定的缺口组合,用left保存缺口重叠的起点,right保存缺口重叠的终点。left初始化为第1个圆盘的缺口起点,right初始化为第1个圆盘的缺口终点。然后遍历后面的圆盘,计算重叠部分,更新left,right。如果计算到最后都有重叠,则此缺口组合满足光可以通过。如果计算过程中right > left则不能使光通过。计算过程中涉及到的角度转换问题详见代码。
代码:
/*
ID: zc.rene1
LANG: C
PROG: spin
*/
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
int speeds[5];
int wedge_num[5];
int wedges[5][5][2];
void Rotate(void)
{
int i, j;
for (i=0; i<5; i++)
{
for (j=0; j<wedge_num[i]; j++)
{
wedges[i][j][0] = (wedges[i][j][0] + speeds[i]) % 360;
wedges[i][j][1] = (wedges[i][j][1] + speeds[i]) % 360;
}
}
}
int min(int a, int b)
{
return a < b ? a : b;
}
int max(int a, int b)
{
return a > b ? a : b;
}
int CanPass(int *index)
{
int left = wedges[0][index[0]][0];
int right = wedges[0][index[0]][1];
int i, temp_left, temp_right;
for (i=1; i<5; i++)
{
if (right < left)
{
right += 360;
}
else
{
left += 360;
right += 360;
}
temp_left = wedges[i][index[i]][0];
temp_right = wedges[i][index[i]][1];
if (temp_right < temp_left)
{
temp_right += 360;
}
else
{
temp_left += 360;
temp_right += 360;
}
left = max(left, temp_left);
right = min(right, temp_right);
if (right < left)
{
return 0;
}
else
{
left %= 360;
right %= 360;
}
}
return 1;
}
int Check(void)
{
int index[5];
for (index[0]=0; index[0]<wedge_num[0]; index[0]++)
{
for (index[1]=0; index[1]<wedge_num[1]; index[1]++)
{
for (index[2]=0; index[2]<wedge_num[2]; index[2]++)
{
for (index[3]=0; index[3]<wedge_num[3]; index[3]++)
{
for (index[4]=0; index[4]<wedge_num[4]; index[4]++)
{
if (CanPass(index))
{
return 1;
}
}
}
}
}
}
return 0;
}
int main(void)
{
FILE *fin, *fout;
int i, j, angle, angle_size;
fin = fopen("spin.in", "r");
fout = fopen("spin.out", "w");
memset(wedges, -1, 5*5*2*sizeof(int));
for (i=0; i<5; i++)
{
fscanf(fin, "%d %d", &speeds[i], &wedge_num[i]);
for (j=0; j<wedge_num[i]; j++)
{
fscanf(fin, "%d %d", &angle, &angle_size);
wedges[i][j][0] = angle;
wedges[i][j][1] = (angle + angle_size) % 360;
}
}
for (i=0; i<360; i++)
{
if (Check())
{
break;
}
Rotate();
}
if (i < 360)
{
fprintf(fout, "%d\n", i);
}
else
{
fprintf(fout, "none\n");
}
return 0;
}