刷紫书第三章例题(例题3-4,3-5,3-6)

来源:互联网 发布:软件实施培训 编辑:程序博客网 时间:2024/06/06 17:32

例题3-4 Master-Mind Hints UVA - 340

MasterMind is a game for two players. One of them, Designer, selects a secret code. The other, Breaker,
tries to break it. A code is no more than a row of colored dots. At the beginning of a game, the players
agree upon the length N that a code must have and upon the colors that may occur in a code.
In order to break the code, Breaker makes a number of guesses, each guess itself being a code. After
each guess Designer gives a hint, stating to what extent the guess matches his secret code.
In this problem you will be given a secret code s1 … sn and a guess g1 … gn, and are to determine
the hint. A hint consists of a pair of numbers determined as follows.
A match is a pair (i, j), 1 ≤ i ≤ n and 1 ≤ j ≤ n, such that si = gj . Match (i, j) is called strong
when i = j, and is called weak otherwise. Two matches (i, j) and (p, q) are called independent when
i = p if and only if j = q. A set of matches is called independent when all of its members are pairwise
independent.
Designer chooses an independent set M of matches for which the total number of matches and the
number of strong matches are both maximal. The hint then consists of the number of strong followed
by the number of weak matches in M. Note that these numbers are uniquely determined by the secret
code and the guess. If the hint turns out to be (n, 0), then the guess is identical to the secret code.
Input
The input will consist of data for a number of games. The input for each game begins with an integer
specifying N (the length of the code). Following these will be the secret code, represented as N integers,
which we will limit to the range 1 to 9. There will then follow an arbitrary number of guesses, each
also represented as N integers, each in the range 1 to 9. Following the last guess in each game will be
N zeroes; these zeroes are not to be considered as a guess.
Following the data for the first game will appear data for the second game (if any) beginning with a
new value for N. The last game in the input will be followed by a single ‘0’ (when a value for N would
normally be specified). The maximum value for N will be 1000.
Output
The output for each game should list the hints that would be generated for each guess, in order, one hint
per line. Each hint should be represented as a pair of integers enclosed in parentheses and separated by
a comma. The entire list of hints for each game should be prefixed by a heading indicating the game
number; games are numbered sequentially starting with 1. Look at the samples below for the exact
format.
Sample Input
4
1 3 5 5
1 1 2 3
4 3 3 5
6 5 5 1
6 1 3 5
1 3 5 5
0 0 0 0
10
1 2 2 2 4 5 6 6 6 9
1 2 3 4 5 6 7 8 9 1
1 1 2 2 3 3 4 4 5 5
1 2 1 3 1 5 1 6 1 9
1 2 2 5 5 5 6 6 6 7
0 0 0 0 0 0 0 0 0 0
0
Sample Output
这里写图片描述

(一)我的AC代码(注意输出格式!!!):

思路:具体参看下面代码,先统计出cnt1,再用数组a扫数组b,用两个标记数组mark_a,mark_b分别对统计过的数组a,b进行标记。

#include<cstdio>#include<cstring>//#define LOCALusing namespace std;int main(){    #ifdef LOCAL    freopen("input.txt","r",stdin);    freopen("output.txt","w",stdout);    #endif    int n,kase=0;    int a[1005],b[1005];    bool mark_a[1005],mark_b[1005];    while(scanf("%d",&n)!=EOF && n)    {        printf("Game %d:\n",++kase);        for(int i=0;i<n;i++)            scanf("%d",&a[i]);        while(1)        {            int cnt1=0,cnt2=0;            memset(mark_a,false,sizeof(mark_a));            memset(mark_b,false,sizeof(mark_b));            for(int i=0;i<n;i++)            {                 scanf("%d",&b[i]);                 if(b[i]==a[i]){mark_a[i]=true;mark_b[i]=true;cnt1++;}            }            if(b[0]==0)break;            for(int i=0;i<n;i++)            {                for(int j=0;j<n;j++)                {                    if(!mark_a[i] && !mark_b[j] && a[i]==b[j])                    {                        cnt2++;                        mark_a[i]=true;                        mark_b[j]=true;                    }                }            }            printf("    (%d,%d)\n",cnt1,cnt2);        }    }    return 0;}

(二)书本代码:

思路分析:先统计出cnt1,由于所有的数字都是1到9,可以统计出数组a,b中出现1到9各个数字的总数,取各个数字总数的较小值,把这些较小值相加,再减去cnt1,就是我们想要的cnt2了。

#include<cstdio>#include<cstring>//#define LOCALusing namespace std;int main(){    #ifdef LOCAL    freopen("input.txt","r",stdin);    freopen("output.txt","w",stdout);    #endif    int n,kase=0;    int a[1005],b[1005];    while(scanf("%d",&n)!=EOF && n)    {        printf("Game %d:\n",++kase);        for(int i=0;i<n;i++)            scanf("%d",&a[i]);        while(1)        {            int cnt1=0,cnt2=0;            for(int i=0;i<n;i++)            {                 scanf("%d",&b[i]);                 if(b[i]==a[i])cnt1++;            }            if(b[0]==0)break;            for(int i=1;i<=9;i++)            {                int n1=0,n2=0;                for(int j=0;j<n;j++)                {                    if(a[j]==i)n1++;                    if(b[j]==i)n2++;                }                cnt2+=n1<n2?n1:n2;            }            printf("    (%d,%d)\n",cnt1,cnt2-cnt1);        }    }    return 0;}

例题3-5 Digit Generator UVA - 1583

For a positive integer N, the digit-sum of N is defined as the sum of N itself and its digits. When M
is the digitsum of N, we call N a generator of M.
For example, the digit-sum of 245 is 256 (= 245 + 2 + 4 + 5). Therefore, 245 is a generator of
256.
Not surprisingly, some numbers do not have any generators and some numbers have more than one
generator. For example, the generators of 216 are 198 and 207.
You are to write a program to find the smallest generator of the given integer.
Input
Your program is to read from standard input. The input consists of T test cases. The number of test
cases T is given in the first line of the input. Each test case takes one line containing an integer N,
1 ≤ N ≤ 100, 000.
Output
Your program is to write to standard output. Print exactly one line for each test case. The line is to
contain a generator of N for each test case. If N has multiple generators, print the smallest. If N does
not have any generators, print ‘0’.
Sample Input
3
216
121
2005
Sample Output
198
0
1979
【我的思路】
暴力枚举
(一)超时代码:

#include<cstdio>//#define LOCALusing namespace std;int div_sum(int tmp){    int sum=tmp;    int n=tmp;    while(n/10>0)    {        sum+=(n%10);        n/=10;    }    sum+=n;    return sum;}int main(){    #ifdef LOCAL    freopen("input.txt","r",stdin);    freopen("output.txt","w",stdout);    #endif    int t;    scanf("%d",&t);    while(t--)    {        int n;        scanf("%d",&n);        bool flag=0;        for(int i=1;i<n;i++)        {            if(div_sum(i)==n)            {                printf("%d\n",i);                flag=1;                break;            }        }        if(!flag)printf("0\n");    }    return 0;}

(二)参考书本代码(预处理):

#include<cstdio>int div_sum(int n){    int sum=n;    while(n/10>0)    {        sum+=(n%10);        n/=10;    }    sum+=n;    return sum;}int main(){    int t,n,a[110000]={0};    for(int i=100000;i>=1;i--)        a[div_sum(i)]=i;    scanf("%d",&t);    while(t--)    {        scanf("%d",&n);        printf("%d\n",a[n]);    }    return 0;}

例题3-6 Circular Sequence UVA - 1584

Some DNA sequences exist in circular forms as in
the following figure, which shows a circular sequence
“CGAGTCAGCT”, that is, the last symbol “T” in
“CGAGTCAGCT” is connected to the first symbol “C”. We always read a circular sequence in the clockwise direction.
Since it is not easy to store a circular sequence in a computer as it is, we decided to store it as a linear sequence.
However, there can be many linear sequences that are obtained from a circular sequence by cutting any place of the
circular sequence. Hence, we also decided to store the linear
sequence that is lexicographically smallest among all linear
sequences that can be obtained from a circular sequence.
Your task is to find the lexicographically smallest sequence
from a given circular sequence. For the example in the figure,
the lexicographically smallest sequence is “AGCTCGAGTC”. If there are two or more linear sequences that
are lexicographically smallest, you are to find any one of them (in fact, they are the same).
Input
The input consists of T test cases. The number of test cases T is given on the first line of the input
file. Each test case takes one line containing a circular sequence that is written as an arbitrary linear
sequence. Since the circular sequences are DNA sequences, only four symbols, ‘A’, ‘C’, ‘G’ and ‘T’, are
allowed. Each sequence has length at least 2 and at most 100.
Output
Print exactly one line for each test case. The line is to contain the lexicographically smallest sequence
for the test case.
Sample Input
2
CGAGTCAGCT
CTCC
Sample Output
AGCTCGAGTC
CCCT

AC代码(枚举所有排列,同时找最小):

#include<cstdio>#include<cstring>int main(){    int t;    char s1[105],s2[105],mmin[105];    scanf("%d",&t);    while(t--)    {        scanf("%s",s1);        strcpy(mmin,s1);        int len=strlen(s1);        for(int i=1;i<len;i++)        {            int cnt=0;            for(int j=i;j<i+len;j++)            {                s2[cnt++]=s1[j%len];            }            s2[cnt]='\0';            if(strcmp(s2,mmin)<0)strcpy(mmin,s2);        }        printf("%s\n",mmin);    }    return 0;}

汉字倒序输出哈哈

#include<cstdio>#include<cstring>int main(){    char s[]="华中师大";    for(int i=strlen(s)-1;i>=0;i-=2)        printf("%c%c",s[i-1],s[i]);    return 0;}
原创粉丝点击