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

概述

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

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

遗漏知识点

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
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值