您的位置:首页 > 其它

USACO section 3.2 Spinning Wheels(模拟)

2012-11-02 20:17 393 查看
Spinning Wheels

1998 ACM NE Regionals
Each of five opaque spinning wheels has one or more wedges cut out of its edges. These wedges must be aligned quickly and correctly. Each wheel also has an alignment mark (at 0 degrees) so that the wheels can all be started in a known position. Wheels rotate
in the `plus degrees' direction, so that shortly after they start, they pass through 1 degree, 2 degrees, etc. (though probably not at the same time).

This is an integer problem. Wheels are never actually at 1.5 degrees or 23.51234123 degrees. For example, the wheels are considered to move instantaneously from 20 to 25 degrees during a single second or even from 30 to 40 degrees if the wheel is spinning
quickly.

All angles in this problem are presumed to be integers in the range 0 <= angle <= 359. The angle of 0 degrees follows the angle of 359 degrees. Each wheel rotates at a certain integer number of degrees per second, 1 <= speed <= 180.

Wedges for each wheel are specified by an integer start angle and integer angle size (or `extent'), both specified in degrees. Wedges in the test data will be separated by at least one degree. The 'extent' also includes the original "degree" of the wedge,
so '0 180' means degrees 0..180 inclusive -- one more than most would imagine.

At the start, which is time 0, all the wheels' alignment marks line up. Your program must determine the earliest time (integer seconds) at or after the start that some wedge on each wheel will align with the wedges on the other wheel so that a light beam
can pass through openings on all five wedges. The wedges can align at any part of the rotation.

PROGRAM NAME: spin

INPUT FORMAT

Each of five input lines describes a wheel.

The first integer on an input line is the wheel's rotation speed. The next integer is the number of wedges, 1 <= W <= 5. The next W pairs of integers tell each wedge's start angle and extent.

SAMPLE INPUT (file spin.in)

30 1 0 120
50 1 150 90
60 1 60 90
70 1 180 180
90 1 180 60

OUTPUT FORMAT

A single line with a single integer that is the first time the wedges align so a light beam can pass through them. Print `none' (lower case, no quotes) if the wedges will never align properly.

SAMPLE OUTPUT (file spin.out)

9


思路:

对边界处理的解释:Usaco原题说的缝隙都是整数的,并不是指离散的一格一格的缝隙。比如数对(0,90)并不是指缝隙集合{0,1,2,3,...,89}而是指一个区间[0,90],在这个区间上,任意一个实数点都算在缝隙内。 考虑到数据规模比较小,所以不必离散化区间,用bool[360]来记录每个整数位置是否是缝隙即可。

失误点:官方数据对[0,1][1,2]这种情形也认为是可以透光的,需要注意,轮子转的方向与理解的也有差别///因为这个而花了许多时间,郁闷。

/*
ID:nealgav1
LANG:C++
PROG:spin
*/
#include<fstream>
#include<cstring>
using namespace std;
ifstream cin("spin.in");
ofstream cout("spin.out");
const int mm=367;
const int mod=360;///360度模
const int oo=30000;
bool cicle[6][mm];
int speed[6],pos[6];
int main()
{
int m,s,e;
memset(cicle,0,sizeof(cicle));
memset(pos,0,sizeof(pos));
for(int i=0;i<5;i++)
{
cin>>speed[i]>>m;
while(m--)
{ cin>>s>>e;e++;///因为【1,2】【2,3】认为能透光,所以边界得多加1
for(int j=s;e--;j=(j+1)%mod)cicle[i][j]=1;
}
}
int time=0;bool flag=1;
while(time<oo&&flag)
{
for(int i=0;i<360&&flag;i++)
for(int j=0;j<5;j++)
{
if(!cicle[j][(pos[j]+i)%mod])break;
if(j==4){cout<<time<<"\n";flag=0;}
}
time++;
for(int i=0;i<5;i++)
pos[i]=(pos[i]-speed[i]+mod)%mod;///方向和正常理解的不一样
}
if(time==oo)cout<<"none\n";
}


USER: Neal Gavin Gavin [nealgav1]
TASK: spin
LANG: C++

Compiling...
Compile: OK

Executing...
Test 1: TEST OK [0.000 secs, 3364 KB]
Test 2: TEST OK [0.162 secs, 3364 KB]
Test 3: TEST OK [0.108 secs, 3364 KB]
Test 4: TEST OK [0.000 secs, 3364 KB]
Test 5: TEST OK [0.000 secs, 3364 KB]
Test 6: TEST OK [0.108 secs, 3364 KB]
Test 7: TEST OK [0.000 secs, 3364 KB]
Test 8: TEST OK [0.108 secs, 3364 KB]

All tests OK.
YOUR PROGRAM ('spin') WORKED FIRST TIME!  That's fantastic
-- and a rare thing.  Please accept these special automated
congratulations.

Here are the test data inputs:

------- test 1 ----
30 1 0 120
180 1 10 100
35 1 20 90
31 1 30 80
32 1 50 60
------- test 2 ----
30 1 350 350
180 1 10 100
35 1 67 23
31 1 30 4
32 1 50 7
------- test 3 ----
180 1 0 120
180 1 120 120
180 1 240 120
31 1 30 4
32 1 50 7
------- test 4 ----
1 1 140 3591 1 200 3591 1 4 1
2 1 6 1
1 1 300 300
------- test 5 ----
45 5 140 13 300 17 0 15 20 3 40 1
73 1 200 359105 2 4 1 50 50
179 3 6 1 8 1 359 3
3 1 300 300
------- test 6 ----
45 5 120 13 200 17 0 15 20 3 32 1
73 5 200 100 1 30 50 10 70 2 75 1
105 2 100 1 50 20
179 3 6 1 8 1 359 3
3 1 300 359------- test 7 ----
73 5 207 101 1 35 57 11 71 2 75 1
45 5 125 13 200 17 0 15 20 3 32 1
96 5 100 12 50 13 0 2 300 39 250 1
119 5 6 1 8 1 359 1 245 1 123 1
15 5 300 1 231 1 185 1 179 2 0 18
------- test 8 ----
73 5 207 11 1 35 57 11 71 2 75 1
45 5 125 3 200 17 0 15 20 3 32 1
96 5 100 1 50 1 0 2 300 39 250 1
119 5 6 1 8 1 359 1 245 1 123 1
15 5 300 1 231 1 185 1 179 2 0 1

Keep up the good work!


Thanks for your submission!

Spinning WheelsHal Burch

The key observation for this problem is that after 360 seconds, the wheels have returned to their original locations, so if the wheels don't line up in 360 seconds, they will never line up.

To determine if there is a location through which a light can be shine, mark, for each wheel, which angles between 0 and 359 a light can be shone through. If any location gets marked for all the wheels, then a light can be shone through the entire system.
Otherwise, no light can be shone through all the wheels.

#include <stdio.h>
#include <assert.h>
#include <string.h>

int speed[5];      /* speed of each wheel */
int wedgest[5][5]; /* start of each wedge (-1 == no wedge) */
int wedglen[5][5]; /* length of each wedge */

int pos[5];        /* angular position of each wheel */
int t;             /* time (in seconds) since start */

/* (light[deg] >> wid) & 0x1 is true if and only if there
is a wedge in wheel wid that a light can shine through at
angle deg */
int light[360];

/* mark all the degrees we can see through wheel w */
void mark_light(int w)
{
int lv, lv2; /* loop variables */
int wpos; /* wedge position */

for (lv = 0; lv < 5; lv++)
{
if (wedglen[w][lv] < 0) /* no more wedges for this wheel */
break;

/* start of wedge */
wpos = (pos[w] + wedgest[w][lv]) % 360;

for (lv2 = 0; lv2 <= wedglen[w][lv]; lv2++)
{ /* throughout extent of wedge */
light[wpos] |= (1 << w); /* mark as hole in wheel */
wpos = (wpos + 1) % 360; /* go to the next degree */
}
}
}

int main(int argc, char **argv)
{
FILE *fp;
FILE *fout;
int w, f;
int lv, lv2;

fp = fopen("spin.in", "r");
fout = fopen("spin.out", "w");
assert(fp);
assert(fout);

/* read in the data */
for (lv = 0; lv < 5; lv++)
{
fscanf (fp, "%d %d", &speed[lv], &w);
for (lv2 = 0; lv2 < w; lv2++)
fscanf (fp, "%d %d", &wedgest[lv][lv2], &wedglen[lv][lv2]);

/* mark the rest of the wedges as not existing for this wheel */
for (; lv2 < 5; lv2++)
wedglen[lv][lv2] = -1;
}

f = 0;
while (t < 360) /* for each time step */
{
memset(light, 0, sizeof(light));

/* mark the degrees we can see through each wheel */
for (lv = 0; lv < 5; lv++)
mark_light(lv);

for (lv = 0; lv < 360; lv++)
if (light[lv] == 31) /* we can shine a light through all five wheels */
f = 1;

if (f) break; /* we found a match! */

/* make a time step */
t++;
for (lv = 0; lv < 5; lv++)
pos[lv] = (pos[lv] + speed[lv]) % 360;
}

/* after 360 time steps, all the wheels have returned to their
original location */
if (t >= 360) fprintf (fout, "none\n");
else fprintf (fout, "%i\n", t);

return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: