PAT乙级题解1-30

1

#include<bits/stdc++.h>
using namespace std;                
int main(){
    int n,cnt=0;
    cin>>n;
    while(n!=1){
        if(n%2==0) n/=2;
        else n=(3*n+1)/2;
        cnt++;
    }
    cout<<cnt;
    return 0;
}

2

#include<bits/stdc++.h>
using namespace std;                
int main(){
    string num[]={"ling","yi","er","san","si",
                    "wu","liu","qi","ba","jiu"};
    string str;
    int ans=0;
    cin>>str;
    for(int i=0;i<str.size();i++)
        ans+=str[i]-'0';
    if(ans>=100)
        cout<<num[ans/100]<<' '<<num[ans%100/10]<<' '<<num[ans%10];
    else if(ans>=10)
        cout<<num[ans/10]<<' '<<num[ans%10];
    else
        cout<<num[ans]; 
    return 0;
}

3

#include<bits/stdc++.h>
using namespace std;
bool Check(string &str){                            //判断函数
    bool ret=true;                                  //统一返回
    int af,am,ab,Pindex,Tindex;                      
    af=am=ab=0;                                     //af、am、ab分别表示P之前 PT之间 T之后的a的个数
    Pindex=Tindex=-1;                               //P和T的下标,初始化为-1,用于判定只出现一次
    for(int i=0;i<str.length();i++){
        switch(str[i]){
            case 'P': if(Pindex==-1) Pindex=i;      //如果是P判定是不是第一次出现,如果是保留下标
                      else ret=false; break;
            case 'A': if(Pindex==-1&&Tindex==-1) af++;//如果PT都未出现,这个a出现再P之前
                      else if(Pindex!=-1&&Tindex==-1) am++;//如果P出现T未出现,这个a出现在P之后
                      else if(Pindex!=-1&&Tindex!=-1) ab++; break;//如果PT都已出现,这个a出现在T之后
            case 'T': if(Tindex==-1) Tindex=i;      //判断T是不是第一次出现,如果是保留下标
                      else ret=false; break;
            default: ret=false; break;              //如果有其他字符
        }
    }
    if((af*am!=ab)||am==0) ret=false;               //必须满足数量关系,由题目第三个条件可知,当中间增加一个A时,T后边线性增加一个P之前的字符串
    if(Pindex>Tindex) ret=false;                    //保证PT出现的先后顺序
    return ret;
}                
int main(){
    int n;
    cin>>n; getchar();
    for(int i=0;i<n;i++){
        string str;
        getline(cin,str);
        if(Check(str)) cout<<"YES"<<endl;
        else cout<<"NO"<<endl;
    }
    return 0;
}

4

#include<bits/stdc++.h>
using namespace std;       
typedef struct Student{
    string name,id;
    int scores;
}STU;
int main(){
    STU stu,max,min;                        //stu用于临时读取一个数据,max和min分别存放需要输出的内容
    max.scores=-1;min.scores=105;
    int n;
    cin>>n;
    for(int i=0;i<n;i++){
        cin>>stu.name>>stu.id>>stu.scores;
        if(stu.scores>max.scores) max=stu;
        if(stu.scores<min.scores) min=stu;
    }
    cout<<max.name<<' '<<max.id<<endl;
    cout<<min.name<<' '<<min.id<<endl;
    return 0;
}

5

#include<bits/stdc++.h>
using namespace std;                
int main(){
    int num[101]={0};                           //用数组对100以内的每一个数字进行标记,初始化为0,其中0号位置用于存放数据个数
    scanf("%d",&num[0]);                        //入读数据个数
    for(int i=0;i<num[0];i++){                  //循环读入
        int temp;
        scanf("%d",&temp);
        if(num[temp]==0) num[temp]=1;           //如果是第一次出现这个数,并且未被覆盖,赋值为1,如果被覆盖过即为2
        while(temp!=1){                         //3n+1猜想验证
            if(temp%2==0) temp/=2;
            else temp=(3*temp+1)/2;
            if(temp<100)    num[temp]=2;        //验证过程中,如果这个数字在100以内,则修改标记为2表示被其他数覆盖
        }
    }
    for(int flag=0,i=100;i>0;i--){              //flag用于控制格式,第一个不输出空格,后边的先输出空格再输出数字
        if(num[i]==1) {                         //如果这个数的标记为1,表示出现在数组中,并且不被其他覆盖,从大到小输出
            if(flag++) putchar(' ');
            cout<<i;
        }
    }
    return 0;
}

6

#include<bits/stdc++.h>
using namespace std;                
int main(){
    int n,bcnt,scnt;
    bcnt=scnt=0;
    cin>>n;
    bcnt=n/100; scnt=n%100/10; n=n%10;      //分解百位 十位和个位的数字 并按照要求输出
    for(int i=0;i<bcnt;i++) putchar('B');
    for(int i=0;i<scnt;i++) putchar('S');
    for(int i=1;i<=n;i++) putchar('0'+i);
    return 0;
}

7

#include<bits/stdc++.h>
using namespace std;
#define MAXN 100005
bool P[MAXN];                           //建立素数表
void getPrime(){
    fill(P,P+MAXN,true);
    P[0]=P[1]=false;
    for(int i=2;i<MAXN;i++){
        if(P[i])
            for(int j=i+i;j<MAXN;j+=i)
                P[j]=false;
    }
}            
int main(){
    getPrime();
    int cnt=0,n;
    cin>>n;
    for(int i=0;i+2<=n;i++){            //遍历并计数
        if(P[i]==true&&P[i+2]==true)    //如果当前的数字和向后相隔两个间距的数字都是素数,进行计数
            cnt++;
    }
    cout<<cnt;
    return 0;
}

8

#include<bits/stdc++.h>
using namespace std;
//创建函数对数组某个区间内的元素进行逆置
void Reverse(int a[],int low,int high){
    while(low<high){
        int temp=a[low];
        a[low]=a[high];
        a[high]=temp;
        low++;high--;
    }
}                
int main(){
    int n,m;
    cin>>n>>m;                          //n为数组大小,m为向右循环移动的元素个数
    m%=n;                               //把m对n取余数,因为对数组整个长度进行循环移位,等同于不移动
    int *a=(int *)malloc(sizeof(int)*n);
    for(int i=0;i<n;i++)
        cin>>a[i];
    Reverse(a,0,n-1);                   //先整体逆置
    Reverse(a,0,m-1);                   //对左边的m个进行逆置
    Reverse(a,m,n-1);                   //对右边的剩余部分进行逆置
    for(int i=0;i<n;i++){               //输出移位后的结果
        if(i) putchar(' ');
        cout<<a[i];
    }
    return 0;
}

9

#include<bits/stdc++.h>
using namespace std;
int main(){
    vector<string> v;
    string str;
    while(cin>>str){                    //读入每一个单词
        v.push_back(str);
    }
    for(int i=v.size()-1;i>=0;i--){     //倒序输出
        if(i!=v.size()-1) putchar(' ');
        cout<<v[i];
    }
    return 0;
}

10

#include<bits/stdc++.h>
using namespace std;
int main(){
    int a, b, flag = 0;                     //a和b分别记录多项式的系数和指数,可能出现负指数
    while (scanf("%d %d",&a,&b)!=EOF) {     //读取测试文件直到末尾
        if (b != 0) {                       //指数为0的即为常数项,常数项求导后为0
            if (flag == 1) putchar(' ');    //第一个对儿输出不需要多余的空格
            printf("%d %d",a*b,b-1);        //输出求导后的系数和指数
            flag = 1;                       //修改标记,已经读入第一对儿数据
        }
    }
    if (flag == 0) printf("0 0");           //如果没有读入过任何一个非常数项,则求导后的为0,按照格式输出
    return 0;
}

11

#include<bits/stdc++.h>
using namespace std;
int main(){
    int n;
    long long a,b,c;
    cin>>n;
    for(int i=1;i<=n;i++){
        cout<<"Case #"<<i<<": ";            //输出头部字符
        cin>>a>>b>>c;
        if(a+b>c) printf("true\n");         //判断并输出
        else printf("false\n");
    }
    return 0;
}

12

#include<bits/stdc++.h>
using namespace std;
int main(){
    int tag[6]={0}, answer[6]={0};                          //tag用于记录每一种的个数,answer用于存放最终结果
    cin>>answer[0];
    for(int i=0;i<answer[0];i++){
        int temp;
        cin>>temp;
        switch(temp%5){
            case 0: if(temp%2==0){                          //被5整除的情况
                        tag[1]++; answer[1]+=temp;
                    }                           break;
            case 1: tag[2]++;                               //余数为1
                    if(tag[2]%2) answer[2]+=temp;           //根据出现的次数确定系数正负
                    else answer[2]-=temp;       break;
            case 2: tag[3]++; answer[3]++;      break;      //余数为2
            case 3: tag[4]++; answer[4]+=temp;  break;      //余数为3
            case 4: if(temp>answer[5]){                     //余数为4
                        tag[5]++; answer[5]=temp;
                    }                           break;
            default: break;
        }
    }
    for(int i=1;i<=5;i++){
        if(i!=1) putchar(' ');                              //格式控制
        if(tag[i]==0){                                      //如果不存在
            putchar('N'); continue;
        }
        if(i==4) printf("%.1f",1.0*answer[i]/tag[4]);       //第四个特殊处理
        else printf("%d",answer[i]);                        //输出结果
    }
    return 0;
}

13

#include<bits/stdc++.h>
using namespace std;
#define MAXN 500000                                 //10000个素数,所以素数表要更大一些
bool Prime[MAXN];
int main(){
    fill(Prime,Prime+MAXN,true);                    //构建素数表
    for(int i=2;i<MAXN;i++){
        if(Prime[i])
            for(int j=2*i;j<MAXN;j+=i)
                Prime[j]=false;
    }
    int m,n,cnt=0,flag=0;                           //cnt用于统计第几个素数,flag用于控制格式
    cin>>m>>n;
    for(int i=2;cnt<n;i++){                         //按照要求输出结果
        if(Prime[i]){
            cnt++;
            if(cnt>m){
                flag++;putchar(flag%10?' ':'\n');
            } 
            if(cnt>=m) cout<<i;
        }
    }
    return 0;
}

14

#include<bits/stdc++.h>
using namespace std;
int main(){
    string str1,str2,str3,str4;
    string WEEK[]={"","MON","TUE","WED","THU","FRI","SAT","SUN"};
    cin>>str1>>str2>>str3>>str4;
    int DAY=-1,H=-1,M=-1,i;
    int len1=min(str1.size(),str2.size());
    int len2=min(str3.size(),str3.size());
    for(i=0;i<len1;i++){                                    //找到第一个代表日子的字符
        if(str1[i]==str2[i]&&str1[i]>='A'&&str1[i]<='G'){   //第一个相同的代表A~G(一周七天)的字母
            DAY=str1[i]-'A'+1; break;
        }      
    }
    for(i++;i<len1;i++){                                    //继而往后找到第二个表示小时的字符
        if(str1[i]==str2[i]){                               //0~9和A~N
            if(str1[i]>='0'&&str1[i]<='9') {H=str1[i]-'0';break;}
            if(str1[i]>='A'&&str1[i]<='N') {H=str1[i]-'A'+10;break;}
        }       
    }
    for(i=0;i<len2;i++){                                    //找到代表分钟数的字符
        if(str3[i]==str4[i]&&isalpha(str3[i])) {M=i; break;}
    }
    cout<<WEEK[DAY];                                        //输出结果
    printf(" %02d:%02d",H,M);
    return 0;
}

15

#include<bits/stdc++.h>
using namespace std;
typedef struct node{
    int id,D,C,sum,rank;
}STU;
bool cmp(const STU&a,const STU&b){
    if(a.rank!=b.rank) return a.rank<b.rank;            //先按照分类顺序排
    else if(a.sum!=b.sum) return a.sum>b.sum;           //同类型人 总分从高到低排
    else if(a.D!=b.D) return a.D>b.D;                   //如果总分相同,按照德分从高到低排
    else return a.id<b.id;
}
int main(){
    int n,L,H;
    STU temp;
    vector<STU> v;
    cin>>n>>L>>H;
    for(int i=0;i<n;i++){                               //读入数据
        cin>>temp.id>>temp.D>>temp.C;
        if(temp.D<L||temp.C<L) continue;                //如果有任何一个分数低于最低要求,视为废弃数据
        if(temp.D>=H&&temp.C>=H) temp.rank=1;           //如果德才都超过最高线,划定为第一类人
        else if(temp.D>=H) temp.rank=2;                 //如果只有德过最高线,划定为第二类人
        else if(temp.D>=temp.C) temp.rank=3;            //如果都不过最高线,但是德分高于才分,划定为第三类人
        else temp.rank=4;                               //剩余的为第四类人
        temp.sum=temp.D+temp.C;
        v.push_back(temp);                              //计算总分并加入排序
    }
    sort(v.begin(),v.end(),cmp);                        //排序后并按照要求输出
    cout<<v.size()<<endl;
    for(int i=0;i<v.size();i++)
        printf("%08d %d %d\n",v[i].id,v[i].D,v[i].C);

    return 0;
}

16

#include<bits/stdc++.h>
using namespace std;
int getnum(char *str,char ch){
    char num[15];
    int i=0;
    while(*str!='\0'){          //将原有字符串中和给出字符相同的读取到num数组中
        if(*str==ch)
            num[i++]=ch;
        str++;
    }
    num[i]='\0';
    sscanf(num,"%d",&i);        //将字符数组转化成数字并返回
    return i;
}
int main(){
    char s1[15],s2[15],ch1,ch2;
    scanf("%s %c %s %c",s1,&ch1,s2,&ch2);   //读取数据
    printf("%d",getnum(s1,ch1)+getnum(s2,ch2)); //计算并打印结果
    return 0;
}

17

#include<bits/stdc++.h>
using namespace std;
int main(){
    char num[1005],*p=num;  //num存放读入的第一个长数字,p工作指针,覆盖存放商
    int b,temp=0;           //b为除数,temp用于存放部分和
    scanf("%s %d",num,&b);  
    for(int i=0;num[i];i++){//循环知道字符数组的结尾
        temp=temp*10+num[i]-'0';    //计算部分和
        num[i]='0'+temp/b;          //覆盖保存商
        temp%=b;                    //计算余数保留到下一次计算
    }                               //余数的位数(包含第一位商0的情况)和被除数一定相同,故不用处理尾部
    if(num[0]=='0'&&num[1]!='\0') p++;  //如果第一位商是0并且整个结果商不是0( 1 2的情况),从下一位非零数字开始输出
    printf("%s %d",p,temp);
    return 0;
}

//1号数据点  商为0
// 1 2

18

#include<bits/stdc++.h>
using namespace std;
int main(){
    int ans[2][4]={0},n;            //记录比赛结果,0表示平,1表示锤子赢,2表示剪刀赢,3表示布赢
    char jia,yi;                    //0号数组表示甲1号表示乙
    scanf("%d\n",&n);
    for(int i=0;i<n;i++){
        scanf("%c %c\n",&jia,&yi);
        switch(jia-yi){
            case 'C'-'J':ans[0][1]++;break; //记录甲赢得情况
            case 'J'-'B':ans[0][2]++;break;
            case 'B'-'C':ans[0][3]++;break;
            case 0:      ans[0][0]++;break;//平局置用记录一次共用即可
            case 'C'-'B':ans[1][3]++;break;//记录乙赢得情况
            case 'J'-'C':ans[1][1]++;break;
            case 'B'-'J':ans[1][2]++;break;
        }
    }
    int temp=ans[0][1]+ans[0][2]+ans[0][3];//统计甲总次数并输出
    printf("%d %d %d\n",temp,ans[0][0],n-temp-ans[0][0]);
    temp=ans[1][1]+ans[1][2]+ans[1][3];    //统计乙总次数并输出
    printf("%d %d %d\n",temp,ans[0][0],n-temp-ans[0][0]);
    if(ans[0][3]>=ans[0][2]&&ans[0][3]>=ans[0][1]) jia='B';//如果B赢得最多
    else if(ans[0][1]>=ans[0][2]) jia='C';                 //如果J赢得最多
    else jia='J';
    if(ans[1][3]>=ans[1][2]&&ans[1][3]>=ans[1][1]) yi='B';
    else if(ans[1][1]>=ans[1][2]) yi='C';
    else yi='J';
    printf("%c %c",jia,yi);                //输出赢得最多得情况
    return 0;
}

19

#include<bits/stdc++.h>
using namespace std;
bool cmp(char a,char b){                //把字符从大到小排序
    return a>b;
}
void reverse(char *str){                //将数组逆置
    swap(str[0],str[3]);
    swap(str[1],str[2]);
}
int main(){
    int n,tmp;
    scanf("%d",&n);
    char str[5];
    while(1){
        sprintf(str,"%04d",n);          //将读入得数字格式化为4位字符串
        sort(str,str+4,cmp);            //从大到小排序
        sscanf(str,"%d",&n);            //获取第一个数
        reverse(str);                   //逆置
        sscanf(str,"%d",&tmp);          //获取第二个数
        printf("%04d - %04d = %04d\n",n,tmp,n-tmp);//输出一组结果
        if(n-tmp==6174||n==tmp) break;  //判断边界
        n-=tmp;                         //处理n,准备进行下一轮
    }
    return 0;
}

20

#include<bits/stdc++.h>
using namespace std;
typedef struct moon{                            //定义月饼结构体,数量可能为浮点类型
    double num,total,price;
}MOON;
bool cmp(MOON &a,MOON &b){                      //月饼按照单价从高到低排序
    return a.price>b.price;             
}
int main(){
    int N,D,cnt=0,i=0;                          //N为月饼种类,D为需求量,题目给出都为正整数
    double sum=0.0;                             //总销售额,为浮点类型
    scanf("%d %d",&N,&D);
    MOON *p=(MOON*)malloc(sizeof(MOON)*N);
    for(i=0;i<N;i++)                            //读取数据并计算单价
        scanf("%lf",&p[i].num);
    for(i=0;i<N;i++){
        scanf("%lf",&p[i].total);
        p[i].price=p[i].total/p[i].num;
    }
    sort(p,p+N,cmp);                            //排序
    i=0;
    while(i<N){                                 //按照单价从高到低遍历
        if(cnt+p[i].num>=D){                    //如果算上当前类型可以满足需求量,则统计并结束循环
            sum+=p[i].price*(D-cnt);
            break;
        }
        sum+=p[i].total;                        //如果算上当前类型仍然不足以满足市场需求,则全部计算在内
        cnt+=p[i].num;
        i++;
    }
    printf("%.2f",sum);                         //输出结果
    return 0;
}

21

#include<bits/stdc++.h>
using namespace std;
int main(){
    int num[10]={0};
    char ch;
    while((ch=getchar())!='\n')             //读取并统计
        num[ch-'0']++;
    for(int i=0;i<10;i++)
        if(num[i])
            printf("%d:%d\n",i,num[i]);     //出现过得字符输出个数
    return 0;
}

22

#include<bits/stdc++.h>
using namespace std;
int main(){
    int a,b,d;                      //根据题目,可知int不越界
    vector<int> v;
    scanf("%d %d %d",&a,&b,&d);
    a+=b;
    do{                             //除留余数法进行进制转换
        b=a%d;
        v.push_back(b);
        a/=d;
    }while(a!=0);
    for(int i=v.size()-1;i>=0;i--)  //倒叙输出转换结果
        printf("%d",v[i]);
    return 0;
}

23

#include<bits/stdc++.h>
using namespace std;
void printchar(char ch,int n){
    for(int i=0;i<n;i++)
        putchar(ch);
}
int main(){
    int num[10]={0},i;
    for(i=0;i<10;i++)
        scanf("%d",&num[i]);
    i=1;
    while(i<10){
        if(num[i]!=0){              //把第一个不为0得数字作为第一个输出的字符
            putchar('0'+i);
            num[i]--;
            break;
        }
        i++;
    }
    if(i==10) putchar('0');         //如果i在while中走到了10,说明全0(因为至少有一个个数非0),输出0
    else 
        for(i=0;i<10;i++)           //剩下的从小到达输出结果
            printchar('0'+i,num[i]);
    return 0;
}

24

#include<bits/stdc++.h>
using namespace std;
int main(){
    int tag=0,i=0,E;                    //tag表示正负,i用于读取字符,E表示指数
    char str[10005]={0},ch;             //数组要初始化,需要用'\0'作为边界,测试编译器有可能不会自动初始化
    ch=getchar();
    if(ch=='-') tag=1;                  //判断正负号
    while(1){                           //小数点和E不接收,E作为边界,用于后序接受指数
        ch=getchar();
        if(ch=='E') break;
        if(ch!='.')
            str[i++]=ch;
    }
    scanf("%d",&E);
    if(tag==1) putchar('-');            //输出负号
    if(E<0){
        E=-E;
        for(int i=0;i<E;i++){           //如果指数小于0,则需要提前输出E个0
            if(i==0) printf("0.");      //其中第一个要带小数点
            else  putchar('0');  
        }
        printf("%s",str);               //输出字符串中有效位
    }
    else{                               //如果指数是正数
        for(int i=0;str[i]!='\0'||i<E+1;i++){
            if(i==E+1) putchar('.');    //由于指数为正,小数点后移,如果小数点出现在有效位的范围内(不在末位),则补充小数点
            putchar(str[i]=='\0'?'0':str[i]);   //有效位范围内输出小数点,否则补充0
        }
    }
    return 0;
}

25

解法一

//使用数组处理的做法
#include<bits/stdc++.h>
using namespace std;
typedef struct node{
    int id,data,next;
}NODE;
NODE LIST[100005];
vector<NODE> v;
void Reverse(vector<NODE> &v,int low,int high){     //对容器中low到high部分进行逆置
    while(low<high){
        swap(v[low],v[high]);
        low++,high--;
    }
}
int main(){
    int Head,N,K;
    scanf("%d %d %d",&Head,&N,&K);          //读取数据
    for(int i=0;i<N;i++){
        int id;
        scanf("%d",&id);
        LIST[id].id=id;
        scanf("%d %d",&LIST[id].data,&LIST[id].next);
    }
    while(Head!=-1){                        //过滤数据,获取整个链表
        v.push_back(LIST[Head]);
        Head=LIST[Head].next;
    }
    N=v.size();                             //统计链表长度
    for(int i=0;i<N/K;i++)
        Reverse(v,i*K,(i+1)*K-1);           //每K个逆置,共逆置N/K次
    for(int i=0;i<N-1;i++)                  //按照格式输出,最后一个特殊处理
        printf("%05d %d %05d\n",v[i].id,v[i].data,v[i+1].id);
    printf("%05d %d -1",v[N-1].id,v[N-1].data);
    return 0;
}

解法二

//使用链表处理的做法
#include<bits/stdc++.h>
using namespace std;
typedef struct node{
    int data,next;
}NODE;
NODE LIST[100005];
int KReverse(int Head,int N,int K){             //将链表每K个逆置的算法
    int cnt=0,dealnum=N-N%K;                    //计数器和总共要处理的元素个数,dealnum
    int NEWHEAD=100000;                         //利用一个空的头结点,方便操作
    LIST[NEWHEAD].next=-1;                      //空的头结点初始化指针域
    int p,tmphead,tmprear;                      //p为工作指针,tmphead为每k个的头结点指针,tmprear为每k个的尾结点指针
    p=tmprear=Head,tmphead=NEWHEAD;             //p初始化为第一个结点,tmprear初始化为第一个结点(逆置后的每k个的尾结点就是顺序的第一个),tmphead初始化为头结点
    while(cnt<dealnum){                         //处理节点
        int temp=LIST[p].next;                  //防断链
        LIST[p].next=LIST[tmphead].next;        //头插代码
        LIST[tmphead].next=p;
        p=temp;     cnt++;                      //勾链并计数
        if(cnt%K==0){                           //每k个更新一次
            tmphead=tmprear;                    //tmphead更新为上一组的尾结点
            tmprear=temp;                       //tmprea更新为下一组的第一个结点
        }
    }
    if(cnt!=N)  LIST[tmphead].next=tmprear;     //如果还有剩余则勾链
    return LIST[NEWHEAD].next;                  //返回新链表的头指针
}
int main(){
    int Head,N,K,p;
    scanf("%d %d %d",&Head,&N,&K);          //读取数据
    for(int i=0;i<N;i++){
        int id;
        scanf("%d",&id);
        scanf("%d %d",&LIST[id].data,&LIST[id].next);
    }
    N=0; p=Head;
    while(p!=-1){                        //过滤数据,统计整个链表的元素个数
        p=LIST[p].next;
        N++;
    }
    if(N>=K) Head=KReverse(Head,N,K);    //如果N>=k则需要逆置
    while(LIST[Head].next!=-1){          //输出链表
        printf("%05d %d %05d\n",Head,LIST[Head].data,LIST[Head].next);
        Head=LIST[Head].next;
    }  
    printf("%05d %d -1\n",Head,LIST[Head].data);    //最后一个结点单独处理
    return 0;
}

26

#include<bits/stdc++.h>
using namespace std;
int main(){
    int c1,c2;
    scanf("%d%d",&c1,&c2);
    c1=(int)(1.0*(c2-c1)/100+0.5);  //计算秒数,+0.5再取整可以得到四舍五入的效果
    printf("%02d:%02d:%02d",c1/3600,c1%3600/60,c1%60); //按照格式进行输出
    return 0;
}

27

#include<bits/stdc++.h>
using namespace std;
void printchar(char ch,int n){  //打印n个ch字符的函数
    for(int i=0;i<n;i++)
        putchar(ch);
}
int main(){
    int n;
    char ch;
    scanf("%d %c",&n,&ch);
    int cnt=(int)sqrt(1.0*(n+1)/2);     //计算层数
    for(int i=0;i<cnt;i++){             //先从多到少打印
        printchar(' ',i);
        printchar(ch,2*(cnt-i)-1);
        putchar('\n');
    }
    for(int i=1;i<cnt;i++){             //再从少到多打印
        printchar(' ',cnt-1-i);
        printchar(ch,2*i+1);
        putchar('\n');
    }
    printf("%d",n-2*cnt*cnt+1);         //输出剩余个数
    return 0;
}

28

#include<bits/stdc++.h>
using namespace std;
int main(){
    int n,cnt=0;                                        //有效个数计数器
    string maxname,minname;                             //存放要输出的名字
    string maxdate="2014/09/06",mindate="1814/09/06";   //存放最大和最小生日,用于更新迭代
    string lowdate="1814/09/06",highdate="2014/09/06";  //有效时间的上下限
    cin>>n;
    for(int i=0;i<n;i++){
        string name,date;
        cin>>name>>date;
        if(date<lowdate||date>highdate) continue;       //不合理日期跳过
        if(date<maxdate){                               //处理有效日期
            maxdate=date;maxname=name;
        }
        if(date>mindate){
            mindate=date;minname=name;
        }
        cnt++;                                          //计数统计
    }
    if(cnt)                                             //特判并输出
        cout<<cnt<<' '<<maxname<<' '<<minname;
    else cout<<cnt;
    return 0;
}
//测试点3为有效日期为0的特判

29

#include<bits/stdc++.h>
using namespace std;
bool findch(char *str,char ch){                     //再一串字符数组中寻找是否出现过ch字符(ch如果为字母,提前转为大写)
    bool ret=false;
    for(int i=0;str[i]!='\0'&&ret==false;i++){
        if(str[i]>='a'&&str[i]<='z'){               //如果检查的字符串是字母,转化成大写进行匹配
            if(str[i]==(ch+'a'-'A'))                //只要匹配到相同的,返回True
                ret=true;
        }
        else if(str[i]==ch) ret=true;               
    }
    return ret;                                     //如果出现过,返回真,否则返回假
}
int main(){
    char in[85],out[85];
    map<char,bool> mp;
    scanf("%s\n%s",in,out);
    for(int i=0;in[i]!='\0';i++){
        if(in[i]>='a'&&in[i]<='z') in[i]=in[i]-'a'+'A';   //转化为大写,进行查找
        if(findch(out,in[i])==false&&mp[in[i]]==false){   //如果出现过且未输出过
            putchar(in[i]);                               //打印并标记
            mp[in[i]]=true;
        }
    }
    return 0;
}

30

#include<bits/stdc++.h>
using namespace std;
bool cmp(int &a,int &b){
    return a<b;
}
int main(){
    int n,p,i,j,*pt;
    int result=0,temp=0;                //result用于存放最终结果,temp存放临时结果,最后取最长
    scanf("%d %d",&n,&p);
    pt=(int*)malloc(sizeof(int)*n);
    for(i=0;i<n;i++)
        scanf("%d",&pt[i]);
    sort(pt,pt+n,cmp);                  //从小到大排序
    for(i=0;i<n;i++){                   //从第一个开始测试
        for(j=i+result;j<n;j++){        //直接判断从已得到的长度开始,是否存在更长的完美数组
            if(pt[j]<=(long long)pt[i]*p)
                temp=j+1-i;
            if(temp>result) result=temp;//如果存在最长的完美数组,继续往后测试是否存在更长,并更新result
            else break;                 //如果不存在,此轮循环结束,i增加到下一个位置
        }
    }
    printf("%d",result);
    return 0;
}

当珍惜每一片时光~