紫书学习——第3章 数组和字符串

来源:互联网 发布:安防 人工智能 fpga 编辑:程序博客网 时间:2024/04/29 14:36

    • 概述
    • 遗漏知识点
    • 例题学习
      • WERTYUuva10082
      • 回文词uva401
      • 猜数字游戏的提示uva340
      • 生成元uva1583
      • 环状序列uva1584
    • 习题学习
      • 得分uva1585
      • 分子量uva1586
      • 数数字uva1225
      • 周期串uva455
      • 谜题uva227
      • 纵横字谜的答案uva232
      • DNA序列uva1368
      • 循环小数uva202
    • 总结
    • 代码

概述

为什么我突然开始又从这基本的语言开始学习呢?因为现在是要练代码,趁早发现自己遗漏的知识点。果然如此。

本文章所有的代码均放在最后。

遗漏知识点

mencpy函数 : 格式 memcpy(b,a,sizeof(a)) ,可能会爆char
空字符 “\0”,单个斜杠”\”
%5d,按照5位数输出
sprintf函数,将串输出到字符串中,但要保证空间
进制问题 %d %o %x 十进制,八进制,十六进制
简单补码知识

例题学习

WERTYU——uva10082

一直纠结于(c=getchar())!=EOF(AC),还是(c=getchar())!=’\n’(WA),查了英文原题,才发现。
Input consists of several lines of text.
1、程序很短,测试时间很长。
2、要养成看英文原题的习惯,虽然英文很烂。

回文词——uva401

程序写得不好,下次改进。机器判别程序(AC),很是严格,少个空行,少个标点都不行。程序没有明显的结束标志,故while(scanf(“%s”,s)==1).原文的char r(char ch)函数技巧性比较高原文(len+1)/2巧妙的处理了长度奇偶性。目前水平,离原文还有一定距离,多琢磨。

猜数字游戏的提示——uva340

开始阶段一团浆糊,只能从数据的输入输出入手,先整理好输入输出格式。不断修改代码的过程中,还能保持一颗平常心,不骄不糙,心性的修炼又上了一个台阶。
又按原书代码方式敲了一遍,发现原书的输出格式比想象的要简单太多,虽然这样的输出格式,照样AC。

生成元——uva1583

隐隐感到此题,制表,查表最快,当不够坚定,瞄了一眼提示(未看代码),与所想一致,开始着手编程。
挺简单一道题,满心欢喜提交,竟然WA,果断查英文原题,原来输入输出格式有限制。
立马提交AC,查看书中代码比本人略胜一筹,做了本人想而未做的对应关系ans[y]=m。

环状序列——uva1584

其实就是定义两个int变量分别记录数组的下坐标,一个用于循环,一个用于记录当前开始最小的字符串的首下坐标

习题学习

截止到2017年3月9日17点,完成8道习题,初步达到书中提到的保证学习效果要求。题目描述书上有就不放了…

得分——uva1585

直接看英文原题的输入输出样例。
看问题没啥感觉和思路,但宗旨是先完善输入输出代码,写着写着,没费啥力,竟然将程序全部写出,一看代码,还挺满意,有点专业的样子,看来这两天训练的效果显现出来了。更简洁的办法,突然间还真想到了,扫描到每个字符时,都要对该字符赋值,加到得分里,根据这个思路很快样例通过

分子量——uva1586

程序思路与习题3-1比较接近,但是调试花了很多时间,对于for循环中的i++有了更深的理解,下一次循环,i要自加1。对将一个个数字拼成一个多位数的整数很有心得。
满心欢喜提交代码,WA,结果发现没有跳出循环,速改,之后AC。

数数字——uva1225

没写之前,思路就已成竹在胸了,直接桶排即可,写下来也比较顺畅,没费什么周折,想也没想肯定一次AC。

周期串——uva455

写的过程抱着试一试的心里,竟然写出,而且代码还写得漂亮,真是想不到,提交PE,明白离成功不远了,又查网站原题,发现漏了一句
Two consecutive input will separated by a blank line.
printf(“%d\n”,k);改成printf(“%d\n\n”,k);提交PE,参考百度内容发现改成
printf(“%d\n”,k);if(T)printf(“\n”);
提交AC,真受不了,核心算法没花什么时间,却在输出格式上费了太多周折。真是服了。

谜题——uva227

程序难在输入输出处理,难在字符读取,策略:写一段代码,跟踪调试一段,正确之后才往下写,其中发现不少错误,一气呵成,写出无误的代码,真的是很难很难啊。让我对getchar()有更深入的理解。没有奢望一次AC,看到的结果是PE还好核心部分没问题,只要修改输出格式即可。又只有参考对代码输出格式进行修改,提交AC.
对Separate output from different puzzle records by one blank line.有更深的理解,输出记录间被空行隔开,但第一条输出记录之前,最后一条输出记录之后,无空行。

纵横字谜的答案——uva232

程序写得很累,一波三折。
先写输入格式,在识别输入的整数是一个还是两个,耽搁了点时间,但很快解决。
先处理Accross部分,字符子串很快解决,但是子串之前的数字序列卡住了。处理竖直Down输出部分,一次成功。直接另外开一个num数组用来记录起始格的数字,不是起始格的数字一律置为0即可,同时在Down处理的时候每个输出的字母的位置在num数组中对应的位置都应该置为0,
防止之后查找的时候将其看做起始格处理了。可是结果是无数的PE,我没有办法,在udebug上都能不被HACK掉,只好抄代码

DNA序列——uva1368

程序还好,搞懂hamming距离(就是两个字符串字对应位不同的数量),然后直接去找即可,结果由于多组数据忘记清零WA了1次

循环小数——uva202

这不就是曾经做过的分数化小数嘛,竟然这里也有做过的水题,但是一看输出顿时呵呵呵,果然这里的题目输出真滴坑爹啊啊啊,不过沉下来打就发现其实并没有想象的那么坑,反而比以前打的代码更加的简便,还是描述下算法:n除以m的余数只能是0~m-1,根据抽屉原则,当计算m+1次时至少存在一个余数相同,即为循环节;存储余数和除数,输出即可。

总结

其实看上去都是水题,没有一点思想方面的东西,但是打起来也并不是每道题都能够轻松AC,而且经常出现PE的情况,而且打代码也不时出现bug,也不时调试很久,正如概述中提到的代码水平还要加强啊,而且这小小的字符串中也有忘记的知识点,基础还得继续打牢固。

代码

都是奇丑无比的代码,仅附上习题代码
uva1585 得分 AC通道:https://vjudge.net/problem/UVA-1585

#include <cstdio>#include <cstring>#include <iostream>using namespace std;int T;string s;int sum,tot;int main(){    scanf("%d",&T);    while(T--)    {        sum = 0,tot = 0;        cin>>s;        for(int i=0;i<s.size();i++)        {               if(s[i]=='O')            {                tot++;                sum+=tot;            }            if(s[i]=='X')                tot=0;        }        printf("%d\n",sum);    }    return 0;}

uva1586 分子量 AC通道:https://vjudge.net/problem/UVA-1586

#include<cstdio>#include<cstring>#include<cctype>const int N = 50;char s[N],abc[]="CHON";int num[4]={0},t=1,i;double sum;int search(char a,char* p) {    int i;    for(i=0;i<4;i++)        if(a==p[i])            return i;}int main() {    int T;    scanf("%d",&T);    while(T--) {        for(i=0;i<=3;i++)             num[i]=0;        sum=0;        scanf("%s",s);        if(isdigit(s[0]))            t=s[0]-'0';        for(i=0;i<strlen(s);i++) {            if(isalpha(s[i])) {                if(isdigit(s[i+1])&&isdigit(s[i+2])) {                    num[search(s[i],abc)]+=(s[i+1]-'0')*10+(s[i+2]-'0');                    continue;                }                if(isdigit(s[i+1])&&(!isdigit(s[i+2])))                    num[search(s[i],abc)]+=s[i+1]-'0';                else num[search(s[i],abc)]++;            }        }        //printf("%d %d %d %d\n",num[0],num[1],num[2],num[3]);        sum=12.01*num[0]+1.008*num[1]+16*num[2]+14.01*num[3];        printf("%.3f\n",t*sum);    }    return 0;}

uva1225 数数字 AC通道: https://vjudge.net/problem/UVA-1225

#include <cstdio>#include <cstring>#include <algorithm>using namespace std;const int size = 10010;int f[size][11];int T,n;void pre() {    memset(f,0,sizeof(f));    for(int i=1;i<size;i++) {        for(int j=0;j<=9;j++)             f[i][j]=f[i-1][j];        int left = i;        while(left) {            f[i][left%10]++;            left/=10;        }    }}int main(){    pre();    scanf("%d",&T);    while (T--) {        scanf("%d",&n);        for (int i = 0 ; i < 9 ; ++ i)            printf("%d ",f[n][i]);        printf("%d\n",f[n][9]);    }    return 0;}

uva455 周期串 AC通道: https://vjudge.net/problem/UVA-455

#include <cstdio>#include <cstring>#include <algorithm>#include <iostream>using namespace std;string s;int T;int main() {    while(~scanf("%d",&T)) {        while(T--) {            cin>>s;            int len = s.size();            for(int i=1,k;i<=len;i++) {                if(len%i==0) {                    for(k=i;k<len;k++)                         if(s[k]!=s[k%i])                            break;                    if(k==len) {                        printf("%d\n",i);                        break;                    }                }            }            if(T)                puts("");        }    }    return 0;}

uva227 谜题 AC通道: https://vjudge.net/problem/UVA-227

#include <cstdio>#include <iostream>#include <cstring>#include <algorithm>using namespace std;string maps[5];char cmd[1001];int cases;int main() {    while(getline(cin,maps[0])) {        if(maps[0][0]=='Z')break;        for(int i=1;i<5;i++)            getline(cin,maps[i]);        int b_x=0,b_y=0;        for(int i=0;i<5;i++)             for(int j=0;j<5;j++)                 if(maps[i][j]==' ') {                    b_x=i;b_y=j;                    break;                }        int count = 0;        while(~scanf("%c",&cmd[count]))             if(cmd[count]!='0') count++;            else break;        cmd[count]=0;getchar();        int x=b_x,y=b_y;        bool flag=false;        for (int i = 0 ; cmd[i] ; ++ i) {            switch(cmd[i]) {                case 'A':   x = b_x-1;y = b_y; break;                case 'B':   x = b_x+1;y = b_y; break;                case 'L':   x = b_x;y = b_y-1; break;                case 'R':   x = b_x;y = b_y+1; break;            }            if (x < 0 || x > 4 || y < 0 || y > 4) {                flag = true;break;            }else {                maps[b_x][b_y] = maps[x][y];                maps[x][y] = ' ';                b_x = x; b_y = y;            }        }        if(cases++) puts("");        printf("Puzzle #%d:\n",cases);        if(flag)             printf("This puzzle has no final configuration.\n");        else {            for(int i=0;i<5;i++) {                printf("%c",maps[i][0]);                for(int j=1;j<5;j++)                     printf(" %c",maps[i][j]);                puts("");            }        }    }    return 0;}

uva 232 纵横字谜的答案 AC通道: https://vjudge.net/problem/UVA-232

#include <cstdio>#include <cstring>using namespace std;const int size = 12;char buf[size][size];int num[size][size];int r,c;int p=1;void Across();void Down();int main(){    while(scanf("%d",&r) && r!=0)    {        scanf("%d",&c);        memset(num,0,sizeof(num));        for(int i=0;i<r;++i)            scanf("%s",buf[i]);        int m=1;        for(int i=0;i<r;++i)        {            for(int j=0;j<c;++j)            {                if(buf[i][j]=='*')                    continue;                if((j-1)<0 || buf[i][j-1]=='*' || (i-1)<0 || buf[i-1][j]=='*')                {                    num[i][j]=m++;                }            }        }        printf("puzzle #%d:\n",p++);        Across();        Down();        puts("");    }    return 0;}void Across() {    printf("Across\n");    for(int i=0;i<r;++i) {        int j=0;        while(j<c) {            if(num[i][j] == 0 || buf[i][j] =='*') {                j++;                continue;            }               printf("%3d.%c",num[i][j],buf[i][j]);            j++;            while(j<c && buf[i][j]!='*') {                printf("%c",buf[i][j]);                j++;            }            printf("\n");        }    }}void Down() {    printf("Down\n");    for(int i=0;i<r;++i) {        for(int j=0;j<c;++j) {            if(num[i][j] == 0 || buf[i][j]=='*')                continue;            printf("%3d.%c",num[i][j],buf[i][j]);            num[i][j]=0;            int k=i+1;            while(k<r && buf[k][j]!='*') {                printf("%c",buf[k][j]);                num[k][j]=0;                k++;            }            printf("\n");        }    }}

uva1368 DNA序列 AC通道: https://vjudge.net/problem/UVA-1368

#include <cstdio>#include <cstring>int t;int n,m;int main(){    scanf("%d",&t);    while(t--){        scanf("%d %d",&n,&m);        char DNA[n][m+1];        for(int i=0;i<n;i++) scanf("%s",DNA[i]);        int list[4];        int num=0,num1;        for(int i=0;i<m;i++){            memset(list,0,sizeof(list));            for(int j=0;j<n;j++){                if(DNA[j][i]=='A') list[0]++;                else if(DNA[j][i]=='C') list[1]++;                else if(DNA[j][i]=='G') list[2]++;                else list[3]++;            }            int temp=0,ans;            for(int k=0;k<4;k++){                if(list[k]>temp) {                ans=k;                temp=list[k];                num1=n-list[k];                }            }            if(ans==0) printf("A");            else if(ans==1) printf("C");            else if(ans==2) printf("G");            else printf("T");            num+=num1;        }        printf("\n%d\n",num);    }        return 0;}

uva202 循环小数 AC通道:https://vjudge.net/problem/UVA-202

#include <iostream>#include <cstdlib>#include <cstring>#include <cstdio>using namespace std;const int size = 3003;int r[size],u[size],s[size];int main(){    int n,m,t;    while (~scanf("%d%d",&n,&m)) {        t = n;        memset(r, 0, sizeof(r));        memset(u, 0, sizeof(u));        int count = 0;        r[count ++] = n/m;        n = n%m;        while (!u[n] && n) {            u[n] = count;            s[count] = n;            r[count ++] = 10*n/m;            n = 10*n%m;        }        printf("%d/%d = %d",t,m,r[0]);        printf(".");        for (int i = 1 ; i < count && i <= 50 ; ++ i) {            if (n && s[i] == n) printf("(");            printf("%d",r[i]);        }        if (!n) printf("(0");        if (count > 50) printf("...");        printf(")\n");        printf("   %d = number of digits in repeating cycle\n\n",!n?1:count-u[n]);    }    return 0;}
0 0
原创粉丝点击