本文编写于 175 天前,最后修改于 173 天前,其中某些信息可能已经过时。

这两天摸鱼玩了下PTA,按顺序从1做到20,难易混合确实不错。之前偶尔学算法用的也是Leetcode的平台再用PTA的平台,PTA的盲样本着实有点难以适应,但另一方面在这种环境下的debug也确实锻炼了分析问题的思维。何况其中不少题对我来说也确实有所挑战,有所收获 (感受到了自己的菜)。

做完20题暂时收手,算是刷下对C的熟练度吧,之后还是得把pwn先学扎实。

L1-001 Hello World (5分)

#include<stdio.h>
int main(){
    printf("Hello World!");
    return 0;
}

L1-002 打印沙漏 (20分)

思路:分上下两个部分打印

#include<stdio.h>
int main(){
    int count;char sig;
    scanf("%d %c",&count,&sig);
    int num,i,j;
    count++;
    for(num=0;count>=0;num++){count-=(num*2+1)*2;}//获取半层数
    count+=(num--*2+1)*2-4;
    for(i=num-1;i>=0;i--){for(j=(num-1-i);j>0;j--)printf(" ");for(j=i*2+1;j>0;j--)printf("%c",sig);printf("\n");}
    for(i=1;i<num;i++){for(j=0;j<(num-1-i);j++)printf(" ");for(j=0;j<i*2+1;j++)printf("%c",sig);printf("\n");}
    printf("%d\n", count);
}

L1-003 个位数统计 (15分)

思路:字符串处理 ascii码

#include <stdio.h>
int main(){
    char s[1000];
    char * p=s;
    int d[10]={0};
    if(scanf("%s",s)){
        while(*p)d[(*p++)-'0']++;
        for(int i=0;i<10;i++)if(d[i]>0)printf("%d:%d\n",i,d[i]);
        return 0;
    }
}

L1-004 计算摄氏温度 (5分)

#include <stdio.h>
int main(){
    int F;
    if(scanf("%d",&F)){
        printf("Celsius = %d",(5*(F-32)/9));
        return 0;
    }
}

L1-005 考试座位号 (15分)

思路:结构化存储后线性查找

#include <stdio.h>
typedef struct{
    char id[17];
    int t_s;
    int e_s;
}stu;
int main(){
    int N, M, test;
    stu stus[1001] = {0};
    int sp[1001]={0};
    scanf("%d", &N);
    for(int i=0; i < N; i++){
        scanf("%s %d %d", stus[i].id,&stus[i].t_s,&stus[i].e_s);
        sp[stus[i].t_s]=i;
    }
    scanf("%d", &M);
    for(int i=0; i < M; i++){
        scanf("%d", &test);
        printf("%s %d\n", stus[sp[test]].id, stus[sp[test]].e_s);
    }
    return 0;    
}

L1-006 连续因子 (20分)

思路:遍历判断因子同时更新最长连续长度

优化:平方根缩小范围

#include <stdio.h>
#include <math.h>
int num;
int main(){
    scanf("%d",&num);
    int first=0,len=0,max=sqrt(num)+1;
    for (int i=2;i<=max;i++){
        int j,temp=1;
        for(j=i;j<=max;j++){
            temp*=j;
            if(num%temp!=0)break;
        }
        if(j-i>len){len=j-i;first=i;}
    }
    if(!first){
        printf("1\n%d",num);
    }else{
        printf("%d\n",len);
        for(int i=0;i<len;i++){
            printf("%d",first+i);
            if(i!=len-1)putchar('*');
        }
    }
    return 0;
}

L1-007 念数字 (10分)

#include<stdio.h>
int talk(char num){
    switch(num){
        case '-':printf("fu");break;
        case '0':printf("ling");break;
        case '1':printf("yi");break;
        case '2':printf("er");break;
        case '3':printf("san");break;
        case '4':printf("si");break;
        case '5':printf("wu");break;
        case '6':printf("liu");break;
        case '7':printf("qi");break;
        case '8':printf("ba");break;
        case '9':printf("jiu");break;
    }
    return 0;
}
int main(){
    char num[1000]={0};
    char *p=num;
    if(scanf("%s",num)){
        while(*p){talk(*p++);if(*(p))printf(" ");}
        return 0;
    }
}

L1-008 求整数段和 (10分)

#include<stdio.h>
int main(){
    int a,b,i;
    scanf("%d %d",&a,&b);
    int sum=0;
    for(i=1;a<=b;a++,i++){
        printf("%5d",a);sum+=a;
        if(!(i%5))printf("\n");
    }
    if(i%5-1)printf("\n");
    printf("Sum = %d",sum);
    return 0;
}

L1-009 N个数求和 (20分)

思路:笔算分数加减的算法

#include<stdio.h>
int gcd(int a,int b){return b?gcd(b,a%b):a;}//辗转相除法取公约
int main(){
    int temp,a,b,c,d,e,n;
    scanf("%d",&n);n--;
    scanf("%d/%d",&a,&b);
    e=gcd(a,b);
    if(a){a/=e;b/=e;}
    while(n--){
        scanf("%d/%d",&c,&d);
        temp=b/gcd(b,d)*d;//分母计算
        a=a*temp/b+c*temp/d;//分母计算
        b=temp;
        e=gcd(a,b);
        if(e){a/=e;b/=e;}//约分
    }
    if(a&&a/b==0)printf("%d/%d",a%b,b);
    else if(a%b==0)printf("%d\n",a/b);
    else printf("%d %d/%d\n",a/b,a%b,b);
    return 0;
}

L1-010 比较大小 (10分)

思路:穷举的快乐

优化:空间换时间

#include <stdio.h>
int main(){
    int num[3];
    scanf("%d %d %d",&num[0],&num[1],&num[2]);
    if  (num[0]<=num[1]&&num[0]<=num[2]&&num[1]<=num[2]){printf("%d->%d->%d",num[0],num[1],num[2]);}
    else if(num[0]<num[1]&&num[0]<num[2]&&num[2]<num[1]){printf("%d->%d->%d",num[0],num[2],num[1]);}
    else if(num[1]<num[0]&&num[1]<num[2]&&num[0]<num[2]){printf("%d->%d->%d",num[1],num[0],num[2]);}
    else if(num[1]<num[0]&&num[1]<num[2]&&num[2]<num[0]){printf("%d->%d->%d",num[1],num[2],num[0]);}
    else if(num[2]<num[0]&&num[2]<num[1]&&num[0]<num[1]){printf("%d->%d->%d",num[2],num[0],num[1]);}
    else if(num[2]<num[0]&&num[2]<num[1]&&num[1]<num[0]){printf("%d->%d->%d",num[2],num[1],num[0]);}
    return 0;
}

L1-011 A-B (20分)

思路:和leetcode宝石与石头异曲同工

#include<stdio.h>
#include<string.h>
int main(){
    char A[10001],B[10001];
    gets(A);gets(B);
    for(int i=0;A[i];i++)if(!strchr(B,A[i]))putchar(A[i]);
    return 0;
}

L1-012 计算指数 (5分)

#include<stdio.h>
int main(){
    int N;
    scanf("%d",&N);
    int reslut=2;
    for(int i=N;i>1;i--)reslut*=2;
    printf("2^%d = %d",N,reslut);
    return 0;
}

L1-013 计算阶乘和 (10分)

思路:算式展开重整

#include<stdio.h>
int main(){
    int N;
    scanf("%d",&N);
    int sum=0;
    for(;N>0;N--)sum=(sum+1)*N;
    printf("%d",sum);
    return 0;
}

L1-014 简单题 (5分)

#include<stdio.h>
int main(){
    printf("This is a simple problem.");
    return 0;
}

L1-015 跟奥巴马一起画方块 (15分)

#include <stdio.h>
int main(){
    int size;char C;
    scanf("%d %c",&size,&C);
    for(int i=0;i<(size/2+size%2);i++){for(int j=0;j<size;j++)putchar(C);putchar('\n');}
    return 0;
}

L1-016 查验身份证 (15分)

思路:字符和数字交替使用

#include <stdio.h>
int main(){
    int q[17]={7,9,10,5,8,4,2,1,6,3,7,9,10,5,8,4,2};
    char map[11]="10X98765432";
    char id[100][19];int N;
    scanf("%d",&N);
    int flag=1;
    for(int i=0;i<N;i++)scanf("%s",&id[i]);
    for(int i=0;i<N;i++){
        int sum=0;
        for(int j=0;j<17;j++){
            sum+=q[j]*(id[i][j]-'0');
        }
        if(id[i][17]!=map[sum%11]){printf("%s\n", id[i]);flag=0;}
    }
    if(flag)printf("All passed\n");
}

L1-017 到底有多二 (15分)

#include <stdio.h>
int main(){
    char N[51];char* np=N;
    scanf("%s",&N);
    float two_times=0,neg_flag=0,even_flag=0,len=0;
    float ererer=0;
    if(!(*np-'-')){neg_flag=1;len--;}
    while(*np){
        if(*np++=='2')two_times++;
        len++;
    }
    even_flag=((*--np)-'0')%2?0:1;
    ererer=two_times/len*(1+0.5*neg_flag)*(1+even_flag);
    printf("%.2f%%\n",ererer*100);
    return 0;
}

L1-018 大笨钟 (10分)

#include <stdio.h>
int main(){
    int hh,mm,time;
    scanf("%d:%d",&hh,&mm);
    time=hh-12+((mm>0)?1:0);
    if(time>0)while(time--)printf("Dang");
    else printf("Only %02d:%02d.  Too early to Dang.",hh,mm);
    return 0;
}

L1-019 谁先倒 (15分)

青岛不倒我不倒,雪花不飘我不飘

思路:存好数据一局一局判断就好

没有优化,空间浪费

#include <stdio.h>
int main(){
    int a_max,b_max,turns;
    int a_han[101]={0},b_han[101]={0};
    int a_hua[101]={0},b_hua[101]={0};
    int a_he=0,b_he=0,temp=0;
    scanf("%d %d\n%d",&a_max,&b_max,&turns);
    for(int i=0;i<turns;i++)scanf("%d %d %d %d",&a_han[i],&a_hua[i],&b_han[i],&b_hua[i]);
    for(int i=0;i<turns;i++){
        temp=a_han[i]+b_han[i];
        if(a_hua[i]!=b_hua[i]){
            if(temp==a_hua[i])a_he++;
            if(temp==b_hua[i])b_he++;
            if(a_he>a_max){printf("A\n%d\n",b_he);break;}
            if(b_he>b_max){printf("B\n%d\n",a_he);break;}
        }
    }
    return 0;
}

L1-020 帅到没朋友 (20分)

帅就完事了

思路:输入的时候把有朋友的标记起来 然后查询就好

#include<stdio.h>
int temp,N,M,K,flag=0;
char hash[100000];
int main(){
    scanf("%d",&N);
    for(int i=0;i<N;i++){
        scanf("%d",&K);
        for(int j=0;j<K;j++){
            scanf("%d",&temp);
            if(K>1) hash[temp]++;
        }
    }
    scanf("%d",&M);
    for(int i = 0;i<M;i++){
        scanf("%d",&temp);
        if(hash[temp] == 0){
            hash[temp]--;
            if(flag++)printf(" ");printf("%05d",temp);
        }
    }
    if(!flag) printf("No one is handsome");
    return 0;
}