C++——USACO Section 2.2 题解

来源:互联网 发布:淘宝进口商品 编辑:程序博客网 时间:2024/04/30 15:14

Preface Numbering

A certain book's prefaces are numbered in upper case Roman numerals. Traditional Roman numeral values use a single letter to represent a certain subset of decimal numbers. Here is the standard set:

        I   1     L   50    M  1000        V   5     C  100        X  10     D  500

As many as three of the same marks that represent 10n may be placed consecutively to form other numbers:

  • III is 3
  • CCC is 300

Marks that have the value 5x10n are never used consecutively.

Generally (with the exception of the next rule), marks are connected together and written in descending order to form even more numbers:

  • CCLXVIII = 100+100+50+10+5+1+1+1 = 268

    Sometimes, a mark that represents 10^n is placed before a mark of one of the two next higher values (I before V or X; X before L or C; etc.). In this case, the value of the smaller mark is SUBTRACTED from the mark it precedes:

    • IV = 4
    • IX = 9
    • XL = 40
    This compound mark forms a unit and may not be combined to make another compound mark (e.g., IXL is wrong for 39; XXXIX is correct).

    Compound marks like XD, IC, and XM are not legal, since the smaller mark is too much smaller than the larger one. For XD (wrong for 490), one would use CDXC; for IC (wrong for 99), one would use XCIX; for XM (wrong for 990), one would use CMXC. 90 is expressed XC and not LXL, since L followed by X connotes that successive marks are X or smaller (probably, anyway).

    Given N (1 <= N < 3,500), the number of pages in the preface of a book, calculate and print the number of I's, V's, etc. (in order from lowest to highest) required to typeset all the page numbers (in Roman numerals) from 1 through N. Do not print letters that do not appear in the page numbers specified.

    If N = 5, then the page numbers are: I, II, III, IV, V. The total number of I's is 7 and the total number of V's is 2.

    PROGRAM NAME: preface

    INPUT FORMAT

    A single line containing the integer N.

    SAMPLE INPUT (file preface.in)

    5

    OUTPUT FORMAT

    The output lines specify, in ascending order of Roman numeral letters, the letter, a single space, and the number of times that letter appears on preface page numbers. Stop printing letter totals after printing the highest value letter used to form preface numbers in the specified set.

    SAMPLE OUTPUT (file preface.out)

    I 7V 2
    /*ID: mcdonne1PROG: prefaceLANG: C++*/#include<cstdio>enum e{I,V,X,L,C,D,M};char r[7]={'I','V','X','L','C','D','M'};int n;int p[5],have[7];int v[7]={1,5,10,50,100,500,1000};void plus(int x){int cnt=4;while(x){p[cnt--]=x%10;x/=10;}while(cnt<=4){switch(cnt){case 1:have[M]+=p[cnt];break;case 2:if(p[cnt]==9){++have[M];++have[C];}else if(p[cnt]<9&&p[cnt]>=5){++have[D];have[C]+=p[cnt]-5;}else if(p[cnt]==4){++have[D];++have[C];}else have[C]+=p[cnt];break;case 3:if(p[cnt]==9){++have[C];++have[X];}else if(p[cnt]<9&&p[cnt]>=5){++have[L];have[X]+=p[cnt]-5;}else if(p[cnt]==4){++have[L];++have[X];}else have[X]+=p[cnt];break;case 4:if(p[cnt]==9){++have[X];++have[I];}else if(p[cnt]<9&&p[cnt]>=5){++have[V];have[I]+=p[cnt]-5;}else if(p[cnt]==4){++have[V];++have[I];}else have[I]+=p[cnt];break;}++cnt;}}int main(){freopen("preface.in","r",stdin);freopen("preface.out","w",stdout);scanf("%d",&n);for(int i=1;i<=n;++i) plus(i);for(int i=0;i<=6;++i)if(have[i]) printf("%c %d\n",r[i],have[i]);else break;return 0;}
    Subset Sums
    JRM

    For many sets of consecutive integers from 1 through N (1 <= N <= 39), one can partition the set into two sets whose sums are identical.

    For example, if N=3, one can partition the set {1, 2, 3} in one way so that the sums of both subsets are identical:

    • {3} and {1,2}

    This counts as a single partitioning (i.e., reversing the order counts as the same partitioning and thus does not increase the count of partitions).

    If N=7, there are four ways to partition the set {1, 2, 3, ... 7} so that each partition has the same sum:

    • {1,6,7} and {2,3,4,5}
    • {2,5,7} and {1,3,4,6}
    • {3,4,7} and {1,2,5,6}
    • {1,2,4,7} and {3,5,6}

    Given N, your program should print the number of ways a set containing the integers from 1 through N can be partitioned into two sets whose sums are identical. Print 0 if there are no such ways.

    Your program must calculate the answer, not look it up from a table.

    PROGRAM NAME: subset

    INPUT FORMAT

    The input file contains a single line with a single integer representing N, as above.

    SAMPLE INPUT (file subset.in)

    7

    OUTPUT FORMAT

    The output file contains a single line with a single integer that tells how many same-sum partitions can be made from the set {1, 2, ..., N}. The output file should contain 0 if there are no ways to make a same-sum partition.

    SAMPLE OUTPUT (file subset.out)

    4
    /*ID: mcdonne1PROG: subsetLANG: C++*/#include<cstdio>int n;int a[40]={0,0,0,1,1,0,0,4,7,0,0,35,62,0,0,361,657,0,0,4110,7636,0,0,49910,93846,0,0,632602,1199892,0,0,8273610,15796439,0,0,110826888,212681976,0,0,1512776590,};int main(){freopen("subset.in","r",stdin);freopen("subset.out","w",stdout);scanf("%d",&n);printf("%d\n",a[n]);return 0;}
    Runaround Numbers

    Runaround numbers are integers with unique digits, none of which is zero (e.g., 81362) that also have an interesting property, exemplified by this demonstration:

    • If you start at the left digit (8 in our number) and count that number of digits to the right (wrapping back to the first digit when no digits on the right are available), you'll end up at a new digit (a number which does not end up at a new digit is not a Runaround Number). Consider: 8 1 3 6 2 which cycles through eight digits: 1 3 6 2 8 1 3 6 so the next digit is 6.
    • Repeat this cycle (this time for the six counts designed by the `6') and you should end on a new digit: 2 8 1 3 6 2, namely 2.
    • Repeat again (two digits this time): 8 1
    • Continue again (one digit this time): 3
    • One more time: 6 2 8 and you have ended up back where you started, after touching each digit once. If you don't end up back where you started after touching each digit once, your number is not a Runaround number.

    Given a number M (that has anywhere from 1 through 9 digits), find and print the next runaround number higher than M, which will always fit into an unsigned long integer for the given test data.

    PROGRAM NAME: runround

    INPUT FORMAT

    A single line with a single integer, M

    SAMPLE INPUT (file runround.in)

    81361

    OUTPUT FORMAT

    A single line containing the next runaround number higher than the input value, M.

    SAMPLE OUTPUT (file runround.out)

    81362
    /*ID: mcdonne1PROG: runroundLANG: C++*/#include<cstdio>#include<cstring>#include<algorithm>using namespace std;int n,m,c;int num[11],v1[11],v2[11];void turn(){register int j=m;for(int i=1;i<j;++i)swap(num[i],num[j--]);}bool review(int x){int vis[10];memset(vis,0,sizeof(vis));while(x){if(x%10==0) return false;if(vis[x%10]) return false;vis[x%10]=1;x/=10;}return true;}bool check(int x){memset(num,0,sizeof(num));memset(v1,0,sizeof(v1));memset(v2,0,sizeof(v2));m=1;while(x){if(v1[(num[m]=x%10)]) return false;v1[num[m++]]=true;x/=10;}--m;turn();c=1;while(!v2[num[c]]){v2[num[c]]=1;c+=num[c]%m;if(c>m)c%=m;}if(num[c]!=num[1]) return false;for(int i=1;i<=m;++i)if(!v2[num[i]]) return false;return true;}int main(){freopen("runround.in","r",stdin);freopen("runround.out","w",stdout);    scanf("%d",&n);    for(int i=n+1;;++i)if(review(i)&&check(i)){printf("%d\n",i);return 0;}}
    Party Lamps
    IOI 98

    To brighten up the gala dinner of the IOI'98 we have a set of N (10 <= N <= 100) colored lamps numbered from 1 to N.

    The lamps are connected to four buttons:

    • Button 1: When this button is pressed, all the lamps change their state: those that are ON are turned OFF and those that are OFF are turned ON.
    • Button 2: Changes the state of all the odd numbered lamps.
    • Button 3: Changes the state of all the even numbered lamps.
    • Button 4: Changes the state of the lamps whose number is of the form 3xK+1 (with K>=0), i.e., 1,4,7,...

    A counter C records the total number of button presses.

    When the party starts, all the lamps are ON and the counter C is set to zero.

    You are given the value of counter C (0 <= C <= 10000) and the final state of some of the lamps after some operations have been executed. Write a program to determine all the possible final configurations of the N lamps that are consistent with the given information, without repetitions.

    PROGRAM NAME: lamps

    INPUT FORMAT

    No lamp will be listed twice in the input.

    Line 1:NLine 2:Final value of CLine 3:Some lamp numbers ON in the final configuration, separated by one space and terminated by the integer -1.Line 4:Some lamp numbers OFF in the final configuration, separated by one space and terminated by the integer -1.

    SAMPLE INPUT (file lamps.in)

    101-17 -1

    In this case, there are 10 lamps and only one button has been pressed. Lamp 7 is OFF in the final configuration.

    OUTPUT FORMAT

    Lines with all the possible final configurations (without repetitions) of all the lamps. Each line has N characters, where the first character represents the state of lamp 1 and the last character represents the state of lamp N. A 0 (zero) stands for a lamp that is OFF, and a 1 (one) stands for a lamp that is ON. The lines must be ordered from least to largest (as binary numbers).

    If there are no possible configurations, output a single line with the single word `IMPOSSIBLE'

    SAMPLE OUTPUT (file lamps.out)

    000000000001010101010110110110
    In this case, there are three possible final configurations:
    • All lamps are OFF
    • Lamps 1, 3, 5, 7, 9 are OFF and lamps 2, 4, 6, 8, 10 are ON.
    • Lamps 1, 4, 7, 10 are OFF and lamps 2, 3, 5, 6, 8, 9 are ON.
    /*ID: mcdonne1PROG: lampsLANG: C++*/#include<cstdio>enum e{off=-1,null,on};int n,c,x;int p[100],f[100];int cz[9]={0,1,2,1,1,2,1,2,0};int at[9][6]={{},{-1,-1,-1,-1,-1,-1},{-1,-1,1,1,1,-1},{-1,1,-1,1,-1,1},{-1,1,1,-1,1,1},{1,-1,-1,1,-1,-1},{1,-1,1,-1,1,-1},{1,1,-1,-1,-1,1},{1,1,1,1,1,1}};int main(){freopen("lamps.in","r",stdin);freopen("lamps.out","w",stdout);scanf("%d%d",&n,&c);while(scanf("%d",&x)&&x!=-1) p[x-1]=on;while(scanf("%d",&x)&&x!=-1) p[x-1]=off;bool put=false;for(int i=1;i<=8;++i){for(int j=0;j<n;++j) f[j]=at[i][j%6];bool g=true;for(int j=0;j<n;++j)if(p[j]!=null&&f[j]!=p[j]){g=false;break;}if(g&&(c-cz[i]==0||c-cz[i]>1)){for(int j=0;j<n;++j) printf(f[j]==1 ? "1" : "0");putchar('\n');put=true;}}if(!put) printf("IMPOSSIBLE\n");return 0;}

  • 原创粉丝点击