刷紫书第三章习题(习题3-7到习题3-12)

来源:互联网 发布:淘宝店铺手机怎么登陆 编辑:程序博客网 时间:2024/05/16 06:39

习题3-7 DNA Consensus String UVA - 1368

Figure 1(略).
DNA (Deoxyribonucleic Acid) is the molecule which con￾tains the genetic instructions. It consists of four different
nucleotides, namely Adenine, Thymine, Guanine, and Cyto￾sine as shown in Figure 1. If we represent a nucleotide by
its initial character, a DNA strand can be regarded as a long
string (sequence of characters) consisting of the four charac￾ters A, T, G, and C. For example, assume we are given some
part of a DNA strand which is composed of the following se￾quence of nucleotides:
“Thymine-Adenine-Adenine-Cytosine-Thymine-Guanine-Cytosine￾Cytosine-Guanine-Adenine-Thymine”
Then we can represent the above DNA strand with the
string “TAACTGCCGAT.”
The biologist Prof. Ahn found that a gene X commonly
exists in the DNA strands of five different kinds of animals,
namely dogs, cats, horses, cows, and monkeys. He also discov￾ered that the DNA sequences of the gene X from each animal
were very alike. See Figure 2.
DNA sequence of gene X
Cat: GCATATGGCTGTGCA
Dog: GCAAATGGCTGTGCA
Horse: GCTAATGGGTGTCCA
Cow: GCAAATGGCTGTGCA
Monkey: GCAAATCGGTGAGCA
Figure 2. DNA sequences of gene X in five animals.
Prof. Ahn thought that humans might also have the gene X and decided to search for the DNA
sequence of X in human DNA. However, before searching, he should define a representative DNA
sequence of gene X because its sequences are not exactly the same in the DNA of the five animals. He
decided to use the Hamming distance to define the representative sequence.
The Hamming distance is the number of different characters at each position from two strings of
equal length. For example, assume we are given the two strings “AGCAT” and “GGAAT.” The Hamming
distance of these two strings is 2 because the 1st and the 3rd characters of the two strings are different.
Using the Hamming distance, we can define a representative string for a set of multiple strings of equal
length. Given a set of strings S = {s1, … , sm} of length n, the consensus error between a string y of
length n and the set S is the sum of the Hamming distances between y and each si
in S. If the consensus
error between y and S is the minimum among all possible strings y of length n, y is called a consensus
string of S. For example, given the three strings “AGCAT” “AGACT” and “GGAAT” the consensus string
of the given strings is “AGAAT” because the sum of the Hamming distances between “AGAAT” and the
three strings is 3 which is minimal. (In this case, the consensus string is unique, but in general, there
can be more than one consensus string.) We use the consensus string as a representative of the DNA
sequence. For the example of Figure 2 above, a consensus string of gene X is “GCAAATGGCTGTGCA” and
the consensus error is 7.
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 starts with a line containing two integers
m and n which are separated by a single space. The integer m (4 ≤ m ≤ 50) represents the number
of DNA sequences and n (4 ≤ n ≤ 1000) represents the length of the DNA sequences, respectively. In
each of the next m lines, each DNA sequence is given.
Output
Your program is to write to standard output. Print the consensus string in the first line of each case
and the consensus error in the second line of each case. If there exists more than one consensus string,
print the lexicographically smallest consensus string.
Sample Input
3
5 8
TATGATAC
TAAGCTAC
AAAGATCC
TGAGATAC
TAAGATGT
4 10
ACGTACGTAC
CCGTACGTAG
GCGTACGTAT
TCGTACGTAA
6 10
ATGTTACCAT
AAGTTACGAT
AACAAAGCAA
AAGTTACCTT
AAGTTACCAA
TACTTACCAA
Sample Output
TAAGATAC
7
ACGTACGTAA
6
AAGTTACCAA
12

【思路】
分析题目给出的例子AGCAT” 和“AGACT” 和“GGAAT”找到的应该是 “AGAAT”,分析这个例子就能明白,每个位置上都取出现次数最多的碱基就OK了,如果出现次数最多的碱基不止一个,就用字典序最小的那个碱基就OK了。。
我把最后一句话看错了,以为如果有多组解,要按照字典序输出所有的解,好坑我自己啊!!
If there exists more than one consensus string,
print **the lexicographically smallest consens**us string.

AC代码:

#include<cstdio>#include<cstring>#include<algorithm>using namespace std;typedef struct{    int n;    char c;}node;bool cmp(node n1,node n2){    if(n1.n==n2.n)        return n1.c<n2.c;    return n1.n>n2.n;}int main(){    int t;    char str[10]="ACGT";    scanf("%d",&t);    while(t--)    {        int m,n;        int num[1005][5];        char s[60][1005];        memset(num,0,sizeof(num));        scanf("%d%d",&m,&n);        for(int i=0;i<m;i++)        {            scanf("%s",s[i]);            for(int j=0;j<n;j++)            {                switch(s[i][j])                {                    case 'A':num[j][0]++;break;                    case 'C':num[j][1]++;break;                    case 'G':num[j][2]++;break;                    case 'T':num[j][3]++;break;                }            }        }        char ss[1005];        int cnt=0;        for(int j=0;j<n;j++)        {            node dna[5];            for(int i=0;i<4;i++)            {                dna[i].c=str[i];                dna[i].n=num[j][i];            }            sort(dna,dna+4,cmp);            cnt+=(m-dna[0].n);            putchar(dna[0].c);        }        putchar('\n');        printf("%d\n",cnt);    }    return 0;}

习题3-8 Repeating Decimals UVA - 202

The decimal expansion of the fraction 1/33 is 0.03, where the 03 is used to indicate that the cycle 03
repeats indefinitely with no intervening digits. In fact, the decimal expansion of every rational number
(fraction) has a repeating cycle as opposed to decimal expansions of irrational numbers, which have no
such repeating cycles.
Examples of decimal expansions of rational numbers and their repeating cycles are shown below.
Here, we use parentheses to enclose the repeating cycle rather than place a bar over the cycle.
fraction decimal expansion repeating cycle cycle length
1/6 0.1(6) 6 1
5/7 0.(714285) 714285 6
1/250 0.004(0) 0 1
300/31 9.(677419354838709) 677419354838709 15
655/990 0.6(61) 61 2
Write a program that reads numerators and denominators of fractions and determines their repeating
cycles.

For the purposes of this problem, define a repeating cycle of a fraction to be the first minimal length
string of digits to the right of the decimal that repeats indefinitely with no intervening digits. Thus
for example, the repeating cycle of the fraction 1/250 is 0, which begins at position 4 (as opposed to 0
which begins at positions 1 or 2 and as opposed to 00 which begins at positions 1 or 4).
Input
Each line of the input file consists of an integer numerator, which is nonnegative, followed by an integer
denominator, which is positive. None of the input integers exceeds 3000. End-of-file indicates the end
of input.
Output
For each line of input, print the fraction, its decimal expansion through the first occurrence of the cycle
to the right of the decimal or 50 decimal places (whichever comes first), and the length of the entire
repeating cycle.
In writing the decimal expansion, enclose the repeating cycle in parentheses when possible. If the
entire repeating cycle does not occur within the first 50 places, place a left parenthesis where the cycle
begins — it will begin within the first 50 places — and place ‘…)’ after the 50th digit.
这里写图片描述
【感想】
本题难点是求周期什么时候开始,什么时候结束。这一点其实关键是观察竖式运算的规律即可解决(后面附上图)。还有一点坑我的是格式输出错误,我自认为最后一个输出不换行了,其实是错的。
这里写图片描述
AC代码:

#include<iostream>using namespace std;const int maxn=3005;int main(){    int a,b;    while(cin>>a>>b){        int decimal[maxn],remainder[maxn];        int i=0;        decimal[0]=a/b;        remainder[0]=a%b;        int st,en;        bool flag=0;        for(i=1;;i++){            decimal[i]=remainder[i-1]*10/b;            remainder[i]=remainder[i-1]*10%b;            int j;            for(j=0;j<i;j++){                if(remainder[j]==remainder[i]){                    st=j+1;                    en=i;                    flag=1;                    break;                }            }            if(flag){                break;            }        }        cout<<a<<"/"<<b<<" = "<<a/b<<".";        for(int k=1;k<st;k++)                cout<<decimal[k];            cout<<"(";        if(en<=50){            for(int k=st;k<=en;k++)                cout<<decimal[k];            cout<<")"<<endl;        }        else{            for(int k=st;k<st+50;k++)                cout<<decimal[k];            cout<<"...)"<<endl;        }               cout<<"   "<<en-st+1<<" = number of digits in repeating cycle"<<endl;        cout<<endl;    }    return 0;}

习题3-9 All in All UVA - 10340

You have devised a new encryption technique which encodes a message by inserting between its characters
randomly generated strings in a clever way. Because of pending patent issues we will not discuss in
detail how the strings are generated and inserted into the original message. To validate your method,
however, it is necessary to write a program that checks if the message is really encoded in the final
string.
Given two strings s and t, you have to decide whether s is a subsequence of t, i.e. if you can remove
characters from t such that the concatenation of the remaining characters is s.
Input
The input contains several testcases. Each is specified by two strings s, t of alphanumeric ASCII
characters separated by whitespace. Input is terminated by EOF.
Output
For each test case output, if s is a subsequence of t.
Sample Input
sequence subsequence
person compression
VERDI vivaVittorioEmanueleReDiItalia
caseDoesMatter CaseDoesMatter
Sample Output
Yes
No
Yes
No

AC代码:

#include<iostream>#include<string>using namespace std;int loc(string s,char c,int st){    for(int i=st;i<s.length();i++){        if(s[i]==c)return i;    }       return -1;}int main(){    string s1,s2;    while(cin>>s1>>s2){        int location=0;        bool flag=1;        for(int i=0;i<s1.length();i++){            location=loc(s2,s1[i],location);            if(location==-1){                cout<<"No"<<endl;                flag=0;                break;            }            location++;        }        if(flag)            cout<<"Yes"<<endl;    }    return 0;}

习题3-10 Box UVA - 1587

Ivan works at a factory that produces heavy machinery. He has a simple job — he knocks up wooden
boxes of different sizes to pack machinery for delivery to the customers. Each box is a rectangular
parallelepiped. Ivan uses six rectangular wooden pallets to make a box. Each pallet is used for one side
of the box.
这里写图片描述
Joe delivers pallets for Ivan. Joe is not very smart and often makes mistakes — he brings Ivan
pallets that do not fit together to make a box. But Joe does not trust Ivan. It always takes a lot of
time to explain Joe that he has made a mistake.
Fortunately, Joe adores everything related to computers and sincerely believes that computers never
make mistakes. Ivan has decided to use this for his own advantage. Ivan asks you to write a program
that given sizes of six rectangular pallets tells whether it is possible to make a box out of them.
Input
Input file contains several test cases. Each of them consists of six lines. Each line describes one pallet
and contains two integer numbers w and h (1 ≤ w, h ≤ 10 000) — width and height of the pallet in
millimeters respectively.
Output
For each test case, print one output line. Write a single word ‘POSSIBLE’ to the output file if it is
possible to make a box using six given pallets for its sides. Write a single word ‘IMPOSSIBLE’ if it is not
possible to do so.
Sample Input
1345 2584
2584 683
2584 1345
683 1345
683 1345
2584 683
1234 4567
1234 4567
4567 4321
4322 4567
4321 1234
4321 1234
Sample Output
POSSIBLE
IMPOSSIBLE

AC代码:

#include<iostream>#include<algorithm>using namespace std;typedef struct{    int a;    int b;}rect;rect rec[10];int main(){    while(cin>>rec[0].a>>rec[0].b){        for(int i=1;i<6;i++)            cin>>rec[i].a>>rec[i].b;        rect rec1[10];        bool mark[10]={0};        int cnt=0;        for(int i=0;i<6;i++){            for(int j=0;j<6;j++){                if(!mark[j] && !mark[i] && i!=j && ((rec[i].a==rec[j].a && rec[i].b==rec[j].b)||(rec[i].a==rec[j].b && rec[i].b==rec[j].a))){                    mark[i]=mark[j]=1;                    rec1[cnt].a=rec[i].a;                    rec1[cnt++].b=rec[i].b;                    break;                }            }        }        if(cnt!=3){            cout<<"IMPOSSIBLE"<<endl;        }        else{            if(rec1[0].a==rec1[1].a && min(rec1[0].b,rec1[1].b)==min(rec1[2].a,rec1[2].b) && max(rec1[0].b,rec1[1].b)==max(rec1[2].a,rec1[2].b))                cout<<"POSSIBLE"<<endl;            else if(rec1[0].a==rec1[1].b && min(rec1[0].b,rec1[1].a)==min(rec1[2].a,rec1[2].b) && max(rec1[0].b,rec1[1].a)==max(rec1[2].a,rec1[2].b))                cout<<"POSSIBLE"<<endl;            else if(rec1[0].b==rec1[1].a && min(rec1[0].a,rec1[1].b)==min(rec1[2].a,rec1[2].b) && max(rec1[0].a,rec1[1].b)==max(rec1[2].a,rec1[2].b))                cout<<"POSSIBLE"<<endl;            else if(rec1[0].b==rec1[1].b && min(rec1[0].a,rec1[1].a)==min(rec1[2].a,rec1[2].b) && max(rec1[0].a,rec1[1].a)==max(rec1[2].a,rec1[2].b))                cout<<"POSSIBLE"<<endl;            else                cout<<"IMPOSSIBLE"<<endl;        }    }    return 0;}

习题3-11 Kickdown UVA - 1588

A research laboratory of a world-leading automobile company has received an order to create a special
transmission mechanism, which allows for incredibly efficient kickdown — an operation of switching to
lower gear. After several months of research engineers found that the most efficient solution requires
special gears with teeth and cavities placed non-uniformly. They calculated the optimal flanks of the
gears. Now they want to perform some experiments to prove their findings.
The first phase of the experiment is done with planar toothed sections, not round-shaped gears. A
section of length n consists of n units. The unit is either a cavity of height h or a tooth of height 2h.
Two sections are required for the experiment: one to emulate master gear (with teeth at the bottom)
and one for the driven gear (with teeth at the top).

The stripe is made of an expensive alloy, so the engineers want to use as little of it as possible. You
need to find the minimal length of the stripe which is enough for cutting both sections simultaneously.
Input
The input file contains several test cases, each of them as described below.
There are two lines in the input, each contains a string to describe a section. The first line describes
master section (teeth at the bottom) and the second line describes driven section (teeth at the top).
Each character in a string represents one section unit — 1 for a cavity and 2 for a tooth. The sections
can not be flipped or rotated.
Each string is non-empty and its length does not exceed 100.
Output
For each test case, write to the output a line containing a single integer number — the minimal length
of the stripe required to cut off given sections.
Sample Input
2112112112
2212112
12121212
21212121
2211221122
21212
Sample Output
10
8
15

【反思】
本题一个水题,但就是让我想了几个小时才搞出来,思维啊,真得经常练习,不能停下啊!我的思路就是搞两个数组a,b,其中b数组恒定不变,移动a数组,暴力枚举所有情况,得出最终最小的所求值,具体还是看代码!如下!

AC代码:

#include<iostream>#include<cstring>#include<algorithm>using namespace std;int main(){    char s1[105],s2[105];    while(cin>>s1>>s2)    {        int a[600]={0},b[600]={0};        int len1=strlen(s1);        int len2=strlen(s2);        for(int i=0;i<len1;i++)            a[i]=s1[i]-'0';        int ii=len1;        for(int i=0;i<len2;i++)            b[ii++]=s2[i]-'0';        int minn=len1+len2;        for(int i=1;i<=len1+len2+1;i++)        {            int aa[600]={0};            for(int j=350;j>=0;j--)            {                aa[j+i]=a[j];            }            int c[650]={0};            bool flag1=0;            int cnt=0;            for(int k=0;k<350;k++)            {                c[k]=aa[k]+b[k];                if(c[k]>3)                {                    flag1=1;                    break;                }                else if(c[k])                {                    cnt++;                }            }            if(flag1)continue;            minn=min(minn,cnt);        }        cout<<minn<<endl;    }    return 0;}

习题3-12 Floating-Point Numbers UVA - 11809

Floating-point numbers are represented differently in computers than integers. That is why a 32-bitfloating-point number can represent values in the magnitude of 1038 while a 32-bit integer can onlyrepresent values as high as 232
.Although there are variations in the ways floating-point numbers are stored in Computers, in thisproblem we will assume that floating-point numbers are stored in the following way:
这里写图片描述
Floating-point numbers have two parts mantissa and exponent. M-bits are allotted for mantissaand E bits are allotted for exponent. There is also one bit that denotes the sign of number (If thisbit is 0 then the number is positive and if it is 1 then the number is negative) and another bit thatdenotes the sign of exponent (If this bit is 0 then exponent is positive otherwise negative). The value of
mantissa and exponent together make the value of the floating-point number. If the value of mantissas m then it maintains the constraints 1
2 ≤ m < 1. The left most digit of mantissa must always be 1 tomaintain the constraint 1
2 ≤ m < 1. So this bit is not stored as it is always 1. So the bits in mantissaactually denote the digits at the right side of decimal point of a binary number (Excluding the digitust to the right of decimal point)In the figure above we can see a floating-point number where M = 8 and E = 6. The largest valuehis floating-point number can represent is (in binary) 0.1111111112 ×2
1111112
. The decimal equivalento this number is: 0.998046875 × 2
63 = 920535763834529382410. Given the maximum possible valueepresented by a certain floating point type, you will have to find how many bits are allotted formantissa (M) and how many bits are allotted for exponent (E) in that certain type.nputThe input file contains around 300 line of input. Each line contains a floating-point number F thatdenotes the maximum value that can be represented by a certain floating-point type. The floating pointnumber is expressed in decimal exponent format. So a number AeB actually denotes the value A×10B.A line containing ‘0e0’ terminates input. The value of A will satisfy the constraint 0 < A < 10 andwill have exactly 15 digits after the decimal point.OutputFor each line of input produce one line of output. This line contains the value of M and E. You canassume that each of the inputs (except the last one) has a possible and unique solution. You can alsoassume that inputs will be such that the value of M and E will follow the constraints: 9 ≥ M ≥ 0 and30 ≥ E ≥ 1. Also there is no need to assume that (M + E + 2) will be a multiple of 8.
Sample Input
5.699141892149156e76
9.205357638345294e18
0e0
Sample Output
5 8
8 6
【思考】
本题是个数学题目,具体过程如下,剩下的直接见代码即可!
这里写图片描述
AC代码:

#include<iostream>#include<cmath>#include<string>#include<sstream>using namespace std;int main(){    double a[50][50];    int b[50][50];    for(int m=0;m<=9;m++)    {        for(int e=1;e<=30;e++)        {            double mm=1-pow(2,-m-1);            double ee=pow(2,e)-1;            double t=log10(mm)+ee*log10(2);            b[m][e]=t;            a[m][e]=pow(10,t-b[m][e]);        }    }    string s;    while(cin>>s && s!="0e0")    {        string::iterator it;        for(it=s.begin();*it!='e';it++);        *it=' ';        istringstream ss(s);//百度了下这个用法好        double A;        int B;        ss>>A>>B;        for(int m=0;m<=9;m++)        {            bool flag=0;            for(int e=1;e<=30;e++)            {                //下面又犯了老错误,害我调试好久:b[m][e]=B等号写成赋值号                //下面1e-5这个精度自己控制吧                if(b[m][e]==B && fabs(a[m][e]-A)<1e-5)                {                    cout<<m<<" "<<e<<endl;                    flag=1;                    break;                }            }            if(flag)break;        }    }    return 0;}
原创粉丝点击