C++——USACO Section 3.2 题解

来源:互联网 发布:mac可以玩qq堂吗 编辑:程序博客网 时间:2024/04/30 10:50

Factorials

The factorial of an integer N, written N!, is the product of all the integers from 1 through N inclusive. The factorial quickly becomes very large: 13! is too large to store in a 32-bit integer on most computers, and 70! is too large for most floating-point variables. Your task is to find the rightmost non-zero digit of n!. For example, 5! = 1 * 2 * 3 * 4 * 5 = 120, so the rightmost non-zero digit of 5! is 2. Likewise, 7! = 1 * 2 * 3 * 4 * 5 * 6 * 7 = 5040, so the rightmost non-zero digit of 7! is 4.

PROGRAM NAME: fact4

INPUT FORMAT

A single positive integer N no larger than 4,220.

SAMPLE INPUT (file fact4.in)

7

OUTPUT FORMAT

A single line containing but a single digit: the right most non-zero digit of N! .

SAMPLE OUTPUT (file fact4.out)

4
/*ID: mcdonne1PROG: fact4LANG: C++*/#include<cstdio>int n,m=1;int main(){freopen("fact4.in","r",stdin);freopen("fact4.out","w",stdout);scanf("%d",&n);for(int i=1;i<=n;++i){m*=i;while(m%10==0) m/=10;if(m>10000) m%=10000;}printf("%d\n",m%10);return 0;}


Stringsobits
Kim Schrijvers

Consider an ordered set S of strings of N (1 <= N <= 31) bits. Bits, of course, are either 0 or 1.

This set of strings is interesting because it is ordered and contains all possible strings of length N that have L (1 <= L <= N) or fewer bits that are `1'.

Your task is to read a number I (1 <= I <= sizeof(S)) from the input and print the Ith element of the ordered set for N bits with no more than L bits that are `1'.

PROGRAM NAME: kimbits

INPUT FORMAT

A single line with three space separated integers: N, L, and I.

SAMPLE INPUT (file kimbits.in)

5 3 19

OUTPUT FORMAT

A single line containing the integer that represents the Ith element from the order set, as described.

SAMPLE OUTPUT (file kimbits.out)

10011

/*ID: mcdonne1PROG: kimbitsLANG: C++*/#include<cstdio>long long n,l,t,f[100][100];int main(){freopen("kimbits.in","r",stdin);freopen("kimbits.out","w",stdout);scanf("%lld%lld%lld",&n,&l,&t);for (int i=0;i<=n;++i) f[i][0]=f[0][i]=1;for (int i=1;i<=n;++i)for (int j=1;j<=n;++j)f[i][j]=f[i-1][j]+f[i-1][j-1];for (int i=n;i>=1;--i)if (t>f[i-1][l]){putchar('1');t-=f[i-1][l];--l;}else putchar('0');putchar('\n');return 0;  }

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 12050 1 150 9060 1 60 9070 1 180 18090 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

#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; }

Feed Ratios
1998 ACM Finals, Dan Adkins

Farmer John feeds his cows only the finest mixture of cow food, which has three components: Barley, Oats, and Wheat. While he knows the precise mixture of these easily mixable grains, he can not buy that mixture! He buys three other mixtures of the three grains and then combines them to form the perfect mixture.

Given a set of integer ratios barley:oats:wheat, find a way to combine them IN INTEGER MULTIPLES to form a mix with some goal ratio x:y:z.

For example, given the goal 3:4:5 and the ratios of three mixtures:

        1:2:3        3:7:1        2:1:2
your program should find some minimum number of integer units (the `mixture') of the first, second, and third mixture that should be mixed together to achieve the goal ratio or print `NONE'. `Minimum number' means the sum of the three non-negative mixture integers is minimized.

For this example, you can combine eight units of mixture 1, one unit of mixture 2, and five units of mixture 3 to get seven units of the goal ratio:

    8*(1:2:3) + 1*(3:7:1) + 5*(2:1:2) = (21:28:35) = 7*(3:4:5)

Integers in the goal ratio and mixture ratios are all non-negative and smaller than 100 in magnitude. The number of units of each type of feed in the mixture must be less than 100. The mixture ratios are not linear combinations of each other.

PROGRAM NAME: ratios

INPUT FORMAT

Line 1:Three space separated integers that represent the goal ratiosLine 2..4:Each contain three space separated integers that represent the ratios of the three mixtures purchased.

SAMPLE INPUT (file ratios.in)

3 4 51 2 33 7 12 1 2

OUTPUT FORMAT

The output file should contain one line containing four integers or the word `NONE'. The first three integers should represent the number of units of each mixture to use to obtain the goal ratio. The fourth number should be the multiple of the goal ratio obtained by mixing the initial feed using the first three integers as mixing ratios.

SAMPLE OUTPUT (file ratios.out)

8 1 5 7

#include <stdio.h>/* the goal ratio */int goal[3];/* the ratio of the feeds */int ratios[3][3];/* the best solution found so far */int min;int mloc[4]; /* amounts of ratio 1, 2, and 3, and the amount of ratio 4 prod *//* the amount of each type of component in the feed */int sum[3];int main(int argc, char **argv) {  FILE *fout, *fin;  int lv, lv2, lv3; /* loop variables */  int t, s; /* temporary variables */  int gsum; /* the sum of the amounts of components in the goal mixture */  if ((fin = fopen("ratios.in", "r")) == NULL)   {    perror ("fopen fin");    exit(1);   }  if ((fout = fopen("ratios.out", "w")) == NULL)   {    perror ("fopen fout");    exit(1);   }  /* read in data */  fscanf (fin, "%d %d %d", &goal[0], &goal[1], &goal[2]);  for (lv = 0; lv < 3; lv++)    fscanf (fin, "%d %d %d", ratios[lv]+0, ratios[lv]+1, ratios[lv]+2);  gsum = goal[0] + goal[1] + goal[2];  min = 301; /* worst than possible = infinity */  /* boundary case (this ensures gsum != 0) */  if (gsum == 0)   {    fprintf (fout, "0 0 0 0\n");    return 0;   }  for (lv = 0; lv < 100; lv++)    for (lv2 = 0; lv2 < 100; lv2++)     { /* for each amout of the first two types of mixtures */      sum[0] = lv*ratios[0][0] + lv2*ratios[1][0];      sum[1] = lv*ratios[0][1] + lv2*ratios[1][1];      sum[2] = lv*ratios[0][2] + lv2*ratios[1][2];      if (lv + lv2 > min) break;      for (lv3 = 0; lv3 < 100; lv3++)       {        s = lv + lv2 + lv3;if (s >= min) break; /* worse than we've found already */        /* calculate a guess at the multiples of the goal we've obtained *//* use gsum so we don't have to worry about divide by zero */        t = (sum[0] + sum[1] + sum[2]) / gsum;if (t != 0 && sum[0] == t*goal[0] &&         sum[1] == t*goal[1] && sum[2] == t*goal[2]) { /* we've found a better solution! */  /* update min */  min = s;  /* store the solution */  mloc[0] = lv;  mloc[1] = lv2;  mloc[2] = lv3;  mloc[3] = t; }        /* add another 'bucket' of feed #2 */        sum[0] += ratios[2][0];        sum[1] += ratios[2][1];        sum[2] += ratios[2][2];       }     }  if (min == 301) fprintf (fout, "NONE\n"); /* no solution found */  else fprintf (fout, "%d %d %d %d\n", mloc[0], mloc[1], mloc[2], mloc[3]);  return 0; }

Magic Squares
IOI'96

Following the success of the magic cube, Mr. Rubik invented its planar version, called magic squares. This is a sheet composed of 8 equal-sized squares:

12348765

In this task we consider the version where each square has a different color. Colors are denoted by the first 8 positive integers. A sheet configuration is given by the sequence of colors obtained by reading the colors of the squares starting at the upper left corner and going in clockwise direction. For instance, the configuration of Figure 3 is given by the sequence (1,2,3,4,5,6,7,8). This configuration is the initial configuration.

Three basic transformations, identified by the letters `A', `B' and `C', can be applied to a sheet:

  • 'A': exchange the top and bottom row,
  • 'B': single right circular shifting of the rectangle,
  • 'C': single clockwise rotation of the middle four squares.

Below is a demonstration of applying the transformations to the initial squares given above:

A:87651234B:41235876C:17248635

All possible configurations are available using the three basic transformations.

You are to write a program that computes a minimal sequence of basic transformations that transforms the initial configuration above to a specific target configuration.

PROGRAM NAME: msquare

INPUT FORMAT

A single line with eight space-separated integers (a permutation of {1..8}) that are the target configuration.

SAMPLE INPUT (file msquare.in)

2 6 8 4 5 7 3 1 

OUTPUT FORMAT

Line 1:A single integer that is the length of the shortest transformation sequence.Line 2:The lexically earliest string of transformations expressed as a string of characters, 60 per line except possibly the last line.

SAMPLE OUTPUT (file msquare.out)

7BCABCCB

/*ID: mcdonne1PROG: msquareLANG: C++*/#include<string>#include<cstdio>#include<map>using namespace std;#define _ a[head]#define $ a[tail]#define tl \$[10]=head;\$[0]=_[0]+1;\if(fh($)&&_min>$[0])\{\_min=$[0];\index=tail;\}int _min=0x7fffffff,index,head,tail=1;int a[50000][11],b[9];map <string,bool >m;inline string hash(int x1,int x2,int x3,int x4,int x5,int x6,int x7,int x8){int x[9]={0,x1,x2,x3,x4,x5,x6,x7,x8};string s="";for(int i=1;i<=8;++i) s+=x[i]+48;return s;}inline bool fh(int *x){for(int i=1;i<=8;++i) if(x[i]!=b[i]) return false;return true;}void dg(int x){if(x>0) dg(a[x][10]);if(a[x][9]!=0) putchar(a[x][9]+64);}int main(){freopen("msquare.in","r",stdin);freopen("msquare.out","w",stdout);for(int i=1;i<=8;++i) scanf("%d",&b[i]),a[1][i]=i;for(int i=1;i<=8;++i)if(b[i]!=i) break;else if(i==8){printf("0\n\n");return 0;}while(head<tail){++head;if(!m[hash(_[8],_[7],_[6],_[5],_[4],_[3],_[2],_[1])]){++tail;$[1]=_[8];$[2]=_[7];$[3]=_[6];$[4]=_[5];$[5]=_[4];$[6]=_[3];$[7]=_[2];$[8]=_[1];$[9]=1;m[hash(_[8],_[7],_[6],_[5],_[4],_[3],_[2],_[1])]=true;tl}if(!m[hash(_[4],_[1],_[2],_[3],_[6],_[7],_[8],_[5])]){++tail;$[1]=_[4];$[2]=_[1];$[3]=_[2];$[4]=_[3];$[5]=_[6];$[6]=_[7];$[7]=_[8];$[8]=_[5];$[9]=2;m[hash(_[4],_[1],_[2],_[3],_[6],_[7],_[8],_[5])]=true;tl}if(!m[hash(_[1],_[7],_[2],_[4],_[5],_[3],_[6],_[8])]){++tail;$[1]=_[1];$[2]=_[7];$[3]=_[2];$[4]=_[4];$[5]=_[5];$[6]=_[3];$[7]=_[6];$[8]=_[8];$[9]=3;m[hash(_[1],_[7],_[2],_[4],_[5],_[3],_[6],_[8])]=true;tl}}printf("%d\n",_min);dg(index);putchar('\n');return 0;}

Sweet Butter

Greg Galperin -- 2001

Farmer John has discovered the secret to making the sweetest butter in all of Wisconsin: sugar. By placing a sugar cube out in the pastures, he knows the N (1 <= N <= 500) cows will lick it and thus will produce super-sweet butter which can be marketed at better prices. Of course, he spends the extra money on luxuries for the cows.

FJ is a sly farmer. Like Pavlov of old, he knows he can train the cows to go to a certain pasture when they hear a bell. He intends to put the sugar there and then ring the bell in the middle of the afternoon so that the evening's milking produces perfect milk.

FJ knows each cow spends her time in a given pasture (not necessarily alone). Given the pasture location of the cows and a description of the paths that connect the pastures, find the pasture in which to place the sugar cube so that the total distance walked by the cows when FJ rings the bell is minimized. FJ knows the fields are connected well enough that some solution is always possible.

PROGRAM NAME: butter

INPUT FORMAT

  • Line 1: Three space-separated integers: N, the number of pastures: P (2 <= P <= 800), and the number of connecting paths: C (1 <= C <= 1,450). Cows are uniquely numbered 1..N. Pastures are uniquely numbered 1..P.
  • Lines 2..N+1: Each line contains a single integer that is the pasture number in which a cow is grazing. Cow i's pasture is listed on line i+1.
  • Lines N+2..N+C+1: Each line contains three space-separated integers that describe a single path that connects a pair of pastures and its length. Paths may be traversed in either direction. No pair of pastures is directly connected by more than one path. The first two integers are in the range 1..P; the third integer is in the range (1..225).

SAMPLE INPUT (file butter.in)

3 4 52341 2 11 3 52 3 72 4 33 4 5

INPUT DETAILS

This diagram shows the connections geometrically:
          P2   P1 @--1--@ C1     \    |\      \   | \       5  7  3        \ |   \         \|    \ C3       C2 @--5--@          P3    P4

OUTPUT FORMAT

  • Line 1: A single integer that is the minimum distance the cows must walk to a pasture with a sugar cube.

SAMPLE OUTPUT (file butter.out)

8OUTPUT DETAILS:Putting the cube in pasture 4 means: cow 1 walks 3 units; cow 2 walks 5units; cow 3 walks 0 units -- a total of 8.

/*ID: mcdonne1PROG: butterLANG: C++*/#include<cstdio>#include<cstring>int n,p,c,x,y,z,cnt,ans=0x7fffffff,sum,head,tail;int at[900],to[3000],next[3000],first[900],len[3000],_p[4000],dis[900];bool went[900];inline int read(){int i=0;char c=getchar();while(c<'0'||c>'9') c=getchar();while(c>='0'&&c<='9') i=(i<<3)+(i<<1)+c-48,c=getchar();return i;}inline void add(int x,int y,int z){to[++cnt]=y;len[cnt]=z;next[cnt]=first[x];first[x]=cnt;}int main(){freopen("butter.in","r",stdin);freopen("butter.out","w",stdout);n=read();p=read();c=read();for(int i=1;i<=n;++i) at[i]=read();for(int i=1;i<=c;++i){x=read();y=read();z=read();add(x,y,z);add(y,x,z);}for(int i=1;i<=p;++i){memset(_p,0,sizeof(_p));memset(dis,127,sizeof(dis));memset(went,false,sizeof(went));head=tail=1;dis[i]=0;_p[1]=i;went[i]=true;while(head<=tail){int u=_p[head];went[u]=false;for(int j=first[u];j;j=next[j])if(len[j]+dis[u]<dis[to[j]]){dis[to[j]]=len[j]+dis[u];if(!went[to[j]]){_p[++tail]=to[j];went[to[j]]=true;}}++head;}sum=0;for(int j=1;j<=n;++j) sum+=dis[at[j]];if(ans>sum) ans=sum;}printf("%d\n",ans);return 0;}

原创粉丝点击