PAT乙级(C++)1021-1025

1021. 个位数统计

给定一个k位整数N = dk-1*10k-1 + … + d1*101 + d0 (0<=di<=9, i=0,…,k-1, dk-1>0),请编写程序统计每种不同的个位数字出现的次数。例如:给定N = 100311,则有2个0,3个1,和1个3。

输入格式:
每个输入包含1个测试用例,即一个不超过1000位的正整数N。

输出格式:
对N中每一种不同的个位数字,以D:M的格式在一行中输出该位数字D及其在N中出现的次数M。要求按D的升序输出。

输入样例:
100311
输出样例:
0:2
1:3
3:1


#include <iostream> 
#include <string>
using namespace std;
int main(){
    string s;
    cin>>s;
    int num[10] ={0};

    for(int i=0;i<s.length();i++){
        num[s[i]-'0']++;    
    }
    for(int i=0;i<10;i++){
        if(num[i]!=0)
            cout<<i<<":"<<num[i]<<"\n";
    } 
    return 0;
}

1022. D进制的A+B

输入两个非负10进制整数A和B(<=230-1),输出A+B的D (1 < D <= 10)进制数。

输入格式:
输入在一行中依次给出3个整数A、B和D。

输出格式:
输出A+B的D进制数。

输入样例:
123 456 8
输出样例:
1103


#include <iostream>
using namespace std;
int main(){
    int a,b,d,sum,length;
    cin>>a>>b>>d;
    sum = a+b;
    int result[32] = {0};
    for(int i = 0;i<32;i++){
        result[i] = sum%d;
        sum = (sum - result[i])/d;
        if(sum==0){
            length = i;
            break;
        }           
    }
    for(int i=length;i>=0;i--){
        cout<<result[i];
    }
    return 0;   
}

1023. 组个最小数

给定数字0-9各若干个。你可以以任意顺序排列这些数字,但必须全部使用。目标是使得最后得到的数尽可能小(注意0不能做首位)。例如:给定两个0,两个1,三个5,一个8,我们得到的最小的数就是10015558。

现给定数字,请编写程序输出能够组成的最小的数。

输入格式:
每个输入包含1个测试用例。每个测试用例在一行中给出10个非负整数,顺序表示我们拥有数字0、数字1、……数字9的个数。整数间用一个空格分隔。10个数字的总个数不超过50,且至少拥有1个非0的数字。

输出格式:
在一行中输出能够组成的最小的数。

输入样例:
2 2 0 0 0 3 0 0 1 0
输出样例:
10015558


#include <iostream>
using namespace std;
int main(){
    int count[10]={0};
    int start = 0;
    for(int i=0;i<10;i++){
        cin>>count[i];
    }
    if(count[0]==0){
        start = 1;
    }
    else{ //处理数字含0的特殊情况
        for(int i = 1;i<10;i++){
            if(count[i]!=0){
                cout<<i;
                count[i]--;
                while(count[0]!=0){
                    cout<<0;
                    count[0]--;
                }
                while(count[i]!=0){
                    cout<<i;
                    count[i]--;
                }
                start = i+1;
                break;
            }   
        }
    }
    for(int i=start;i<10;i++){
        while(count[i]!=0){
            cout<<i;
            count[i]--;
        } 
    }
    return 0;
 }

1024. 科学计数法

科学计数法是科学家用来表示很大或很小的数字的一种方便的方法,其满足正则表达式[+-][1-9]”.”[0-9]+E[+-][0-9]+,即数字的整数部分只有1位,小数部分至少有1位,该数字及其指数部分的正负号即使对正数也必定明确给出。

现以科学计数法的格式给出实数A,请编写程序按普通数字表示法输出A,并保证所有有效位都被保留。

输入格式:
每个输入包含1个测试用例,即一个以科学计数法表示的实数A。该数字的存储长度不超过9999字节,且其指数的绝对值不超过9999。

输出格式:
对每个测试用例,在一行中按普通数字表示法输出A,并保证所有有效位都被保留,包括末尾的0。

输入样例1:
+1.23400E-03
输出样例1:
0.00123400
输入样例2:
-1.2E+10
输出样例2:
-12000000000


读题的时候没读仔细——[数字的整数部分只有1位],傻傻地当做可能有很多位处理了。代码同样适用,就懒得改了。


#include <iostream>
#include <string>
#include <stdio.h>
using namespace std;
int main(){
    string s;
    cin>>s;
    int index1 = s.find('.',0);
    int index2 = s.find('E',0);
    string s1,s2,s3;
    int move = 0;
    s1 = s.substr(0,index1);
    s2 = s.substr(index1+1,(index2-index1-1));
    s3 = s.substr(index2+1,s.size());

    for(int i=1;i<s3.size();i++){
        move = move*10 + (s3[i]-'0'); //move是小数点移动的次数 
    }
    if(s3[0]=='-'){
        move = 0-move;
    }
    if(s1[0] == '-'){//输出符号
        cout<<s1[0];
        s1 = s1.substr(1,s1.size());
        index1--; 
        index2--;   
    }
    if(s1[0] == '+'){
        s1 = s1.substr(1,s1.size());
        index1--;
        index2--;   
    }

    if(index1+move<=0){//超出第1位,或者刚好第1位,前补0; 
        cout<<0<<'.';
        int i=index1+move;
        while(i<0){
            cout<<0;
            i++;
        }
        cout<<s1<<s2;   
    }
    else if(index1+move==index2-1){//刚好最末尾,不用输出小数点 
        cout<<s1<<s2;
    }
    else if(index1 + move >index2-1){//超出最末尾,后补0 
        cout<<s1<<s2;
        int i = index1 + move - (index2-1);
        while(i>0){
            cout<<0;
            i--;
        }
    }
    else{
        cout<<s1;
        cout<<s2.substr(0,move);
        cout<<'.';
        cout<<s2.substr(move,s2.size());
    } 
    return 0;
}

1025. 反转链表

给定一个常数K以及一个单链表L,请编写程序将L中每K个结点反转。例如:给定L为1→2→3→4→5→6,K为3,则输出应该为3→2→1→6→5→4;如果K为4,则输出应该为4→3→2→1→5→6,即最后不到K个元素不反转。

输入格式:
每个输入包含1个测试用例。每个测试用例第1行给出第1个结点的地址、结点总个数正整数N(<= 105)、以及正整数K(<=N),即要求反转的子链结点的个数。结点的地址是5位非负整数,NULL地址用-1表示。

接下来有N行,每行格式为:
Address Data Next

其中Address是结点地址,Data是该结点保存的整数数据,Next是下一结点的地址。

输出格式:
对每个测试用例,顺序输出反转后的链表,其上每个结点占一行,格式与输入相同。

输入样例:
00100 6 4
00000 4 99999
00100 1 12309
68237 6 -1
33218 3 00000
99999 5 68237
12309 2 33218
输出样例:
00000 4 33218
33218 3 12309
12309 2 00100
00100 1 99999
99999 5 68237
68237 6 -1


注意1:输入中可能出现不在链表中的点,这些点不输出
思路1:反转的过程中采用首尾交换,节省时间。


#include <iostream>
using namespace std;
struct node{
    int address;
    int value;
    int next;
};

int main(){
    int start,N,K;
    cin>>start>>N>>K;
    node *ll = new node[N];
    node *sorted = new node[N];
    for(int i=0;i<N;i++){
        scanf("%d%d%d",&ll[i].address,&ll[i].value,&ll[i].next);
    }

    //按列表排序
    int count = 0; 
    for(int i=0;i<N;i++){
        int j;
        if(start == -1)
            break;  
        for(j=i;j<N;j++){ //此处j=i,是因为将取出的节点交换到前面,下次不必再访问
            if(ll[j].address == start){
                sorted[i] = ll[j];
                start = ll[j].next; 
                node temp = ll[i];
                ll[i] = ll[j];
                ll[j] = temp;       
                count++;
                break;
            }               
        }   
    }

    //反转 
    for(int i = 0;i<count/K;i++){
        int k = 1;
        for(int j=i*K;j<i*K+K/2;j++){
            node temp;
            temp = sorted[j];
            sorted[j] = sorted[i*K+K-k];
            sorted[i*K+K-k] = temp;
            k++;
        }

    }

    //输出
    for(int i=0;i<count-1;i++){
        printf("%05d %d %05d\n",sorted[i].address,sorted[i].value,sorted[i+1].address);
    }
    printf("%05d %d %d\n",sorted[count-1].address,sorted[count-1].value,-1);            
    return 0;
} 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值