PAT-Thare's Road

仅以此Blog记录PAT甲级习题训练过程

 

1001. A+B Format  ★

  Tips:

  1. 首先判断和的正负,这个比较容易考虑到.

  2. 从高位开始输出,每三位一个分隔,要注意若更高位有过输出,则次位输出的时候不够三位记得补0.
  
#include <stdio.h>

int main() {
    int a,b,c,temp;
    int flag1,flag2;
    while(scanf("%d %d",&a,&b) != EOF){
        c = a + b;
        flag1 = flag2 = 0;
        
        if(c < 0){
            printf("-");
            c = -c;
        }
        if(c / 1000000 > 0){
            printf("%d,",c / 1000000);
            c = c % 1000000;
            flag1 = 1;
        }
        if(c / 1000 > 0 || flag1 == 1){
            temp = c / 1000;
            if(flag1 == 1){
                if(temp > 9 && temp < 100)
                    printf("0");
                else if(temp < 10)
                    printf("00");
            }
            printf("%d,",temp);
            c = c % 1000;
            flag2 = 1;
        }
        if(flag2 == 1){
            if(c > 9 && c < 100)
                printf("0");
            else if(c < 10)
                printf("00");
        }
        printf("%d\n",c);
    }
    return 0;
}
View Code

 

1002. A+B for Polynomials  ★

  Tips:

  1. double数组必须初始化为0.默认虽为0,但是是不准确的0.

  2. 第2行输入的数据在加之前要判断num[i]是不是0,加之后也要判断下是否为0,再对count进行响应操作.

  3. 最后打印数据的时候空格放在数据前打印,若放在后面会造成最后一个数据也打印一个空格,从而格式错误.

  
#include<stdio.h>
#define LEN 1001

int main() {
    double num[LEN];
    int k,a,count,i;
    double b;
    while(scanf("%d",&k) != EOF){
        count = 0;
        for(i = 0;i < LEN;i++)
            num[i] = 0;
        for(i = 0;i < k;i++){
            scanf("%d",&a);
            scanf("%lf",&b);
            num[a] += b;
            count ++;
        }
        scanf("%d",&k);
        for(i = 0;i < k;i++){
            scanf("%d",&a);
            scanf("%lf",&b);
            if(num[a] == 0)
                count ++;
            num[a] += b;
            if(num[a] == 0)
                count --;
        }
        printf("%d",count);
        if(count != 0){
            for(i = LEN - 1;i >= 0;i--){
                if(num[i] != 0){
                    printf(" %d %.1lf",i,num[i]);
                    num[i] = 0;
                }
            }
        }
        printf("\n");
    }
}
View Code

 

 

1005. Spell It Right  ★

  Tips:

  1. 这题算是很简单的一道题了,注意单词不要拼写错误就行.  
  
#include <stdio.h>

char* converse(int n){
    switch(n){
        case 0: return "zero";
        case 1: return "one";
        case 2: return "two";
        case 3: return "three";
        case 4: return "four";
        case 5: return "five";
        case 6: return "six";
        case 7: return "seven";
        case 8: return "eight";
        case 9: return "nine";
        default: return "";
    }
}

int main(){
    char c ;
    int sum = 0;
    while((scanf("%c",&c) != EOF)){
        if(c != 10){
            sum += c - 48;
        }else{
            if(sum > 99)
                printf("%s %s %s\n",converse(sum / 100),converse(sum % 100 / 10),converse(sum % 10));
            else if(sum > 9)
                printf("%s %s\n",converse(sum / 10),converse(sum % 10));
            else
                printf("%s\n",converse(sum));
            sum = 0;
        }
    }
    return 0;
}
View Code

 

1006. Sign In and Sign Out  ★

  Tips:

  1. 这题没什么陷阱,基本上例子能通过也就能AC,所以通过率也蛮高的.
  2. 本题看似有些复杂,需要把字符串时间转换成我们熟悉的int类型来判断时间的早晚.其实这里有个更方便的方法,就是直接利用strcmp(str1,str2)来比较时间.
  3. 注意输完M后getchar()掉回车.
  
#include <stdio.h>
#include <string.h>

int main(){
    int n,i;
    char openPer[16],lockPer[16];
    char openTime[9],lockTime[9];
    char person[16],inTime[9],outTime[9];
    while((scanf("%d",&n) != EOF)){
        if(n == 0)
            continue;
        getchar();
        for(i = 0;i < n;i++){
            scanf("%s %s %s",person,inTime,outTime);
            if(i == 0){
                strcpy(openPer,person);
                strcpy(lockPer,person);
                strcpy(openTime,inTime);
                strcpy(lockTime,outTime);
                continue;
            }
            if(strcmp(openTime,inTime) > 0){
                strcpy(openPer,person);
                strcpy(openTime,inTime);
            }
            if(strcmp(lockTime,outTime) < 0){
                strcpy(lockPer,person);
                strcpy(lockTime,outTime);
            }

        }
        printf("%s %s\n",openPer,lockPer);
    }
    return 0;
}
View Code

 

1007. Maximum Subsequence Sum  ★★

  Tips:

  1. 这题真心是郁闷要死了.自己没有看太清题目,加上题目给的实例又比较特殊,我一直以为后面是输出最大序列的左右两个下标,结果一直只对两个点.后来网上查了下别人的blog再仔细对了下题目,才发现自己理解错误.
  2. 本题注意的点:(1)数列全为负数输出第一位和最后一位.(2)如果数列最大为0,则输出0 0 0即可.(3)如果数列最大子数列最左项和最右项不能为0.
  3. 本题一次循环即可得出结果.边输入边用max2加上刚输入的数,并用max1保存最大的max1,并记录下最左和最右的数.
  
#include <stdio.h>

int main(){
    int k,i,j,max1,max2,index,num,left1,right1,left2,right2,first,flag;
    while((scanf("%d",&k) != EOF)){
        max1 = 0;
        max2 = 0;
        flag = 0;
        left1 = -1;
        i = j = -1;
        for(index = 0;index < k;index++){
            scanf("%d",&num);
            if(index == 0)
                first = num;
            if(num >= 0)
                flag = 1;
            max2 += num;
            if(max2 <= 0){
                max2 = 0;
                i = j = -1;
            }else{
                if(i == -1){
                    i = j = 1;
                    left2 = right2 = num;
                }
                else{
                    j = 1;
                    right2 = num;
                }
                if(max2 > max1){
                    max1 = max2;
                    left1 = left2;
                    right1 = right2;
                }
            }
        }
        if(flag == 0){
            left1 = first;
            right1 = num;
        }else{
            if(left1 == -1)
                left1 = right1 = 0;
        }
        printf("%d %d %d\n",max1,left1,right1);
    }
    return 0;
}
View Code

 

1008. Elevator  ★

  Tips:

  1. 这题实在没什么难度,也就不说什么了.
  
#include <stdio.h>

int main(){
    int n,floor,time,last,gap,i;
    while((scanf("%d",&n) != EOF)){
        time = 0;
        last = 0;
        for(i = 0;i < n;i++){
            scanf("%d",&floor);
            gap = floor - last;
            if(gap > 0)
                time += 6 * gap;
            else
                time -= 4 * gap;
            last = floor;
        }
        time += 5 * n;
        printf("%d\n",time);
    }
    return 0;
}
View Code

 

1009. Product of Polynomials  ★

  Tips:

  1. 本题与1002类似,只不过此题是求乘积,但和1002注意的地方一样.
  2. 还需注意的是,本题开辟的数组空间大小应为2001.
  
#include <iostream>
using namespace std;
#define LEN 2001

int main() {
    int k1,k2,i,j,count;
    int *pCoe;
    double *pIndex;
    int coe;
    double index;
    double *result = new double[LEN];
    for(i = 0;i <LEN;i ++)
            result[i] = 0;
    while(scanf("%d",&k1) != EOF) {
        count = 0;
        pCoe = new int[k1];
        pIndex = new double[k1];
        for(i = 0;i < k1;i ++)
            scanf("%d %lf",&pCoe[i],&pIndex[i]);
        scanf("%d",&k2);
        for(i = 0;i < k2;i ++){
            scanf("%d %lf",&coe,&index);
            for(j = 0;j < k1;j ++){
                if(result[coe + pCoe[j]] == 0)
                    count ++;
                result[coe + pCoe[j]] += index * pIndex[j];
                if(result[coe + pCoe[j]] == 0)
                    count --;
            }
        }
        printf("%d",count);
        for(i = LEN - 1;i >= 0;i --){
            if(result[i] != 0){
                printf(" %d %.1lf",i,result[i]);
                result[i] = 0;
            }
        }
        printf("\n");
    }
    return 0;
}
View Code

 

1011. World Cup Betting  ★

  Tips:

  1. 太简单了,没啥好说的.
  
#include <stdio.h>

int main(){
    int i;
    float d[3][3];
    float dMax[3];
    char t[3] = {'W','T','L'};
    char c[3];
    float money;
    while(scanf("%f %f %f",&d[0][0],&d[0][1],&d[0][2]) != EOF){
        scanf("%f %f %f",&d[1][0],&d[1][1],&d[1][2]);
        scanf("%f %f %f",&d[2][0],&d[2][1],&d[2][2]);
        for(i = 0;i < 3;i ++){
            dMax[i] = d[i][0];
            c[i] = t[0];
            if(dMax[i] < d[i][1]){
                dMax[i] = d[i][1];
                c[i] = t[1];
            }
            if(dMax[i] < d[i][2]){
                dMax[i] = d[i][2];
                c[i] = t[2];
            }
        }
        printf("%c %c %c %.2lf\n",c[0],c[1],c[2],(dMax[0] * dMax[1] * dMax[2] * 0.65 - 1) * 2);
    }
    return 0;
}
View Code

 

1015. Reversible Primes  ★

  Tips:

  1. 这题开始一直没太弄懂题目,以为给出的数是以d为底,相当于d进制(但各位可能比d大),然后转换成10进制,再倒置.结果只能过一个点.而且如果按照我的思路,第二个case应该是No才对.
  2. 最后只能搜搜其它人的答案了.原来是这样做的:先把给出的十进制数转换成d进制,然后这个d进制再逆置,再转换成十进制,再判断.
  3. 最后借鉴了某位浙大大神的代码,其中的转置处理的很nice.原blog地址http://blog.csdn.net/sunbaigui/article/details/8657051.
  
#include <stdio.h>

int isPrime(int n){
    int i;
    if(n < 2)
        return 0;
    for(i = 2;i * i <= n;i ++){
        if(n % i == 0)
            return 0;
    }
    return 1;
}

int numReserve(int n,int d){
    int sum = 0;
    while(n > 0){
        sum = sum * d + n % d;
        n /= d;
    }
    return sum;
}

int main(){
    int n,d;
    while(scanf("%d",&n)){
        if(n < 0)
            break;
        scanf("%d",&d);
        if(isPrime(n) && isPrime(numReserve(n,d)))
            printf("Yes\n");
        else
            printf("No\n");
    }
    return 0;
}
View Code

 

1027. Colors in Mars  ★

  Tips:

  1. 注意大小写.
  
#include <stdio.h>

void p(int a){
    char c;
    if(a < 10)
        c = a + '0';
    else{
        switch(a){
            case 10:
                c = 'A';
                break;
            case 11:
                c = 'B';
                break;    
            case 12:
                c = 'C';
                break;
        }
    }
    printf("%c",c);
}

int main(){
    int color[3];
    int i,a,b;
    while(scanf("%d %d %d",&color[0],&color[1],&color[2]) != EOF){
        printf("#");
        for(i = 0;i < 3;i++){
            p(color[i]/13);
            p(color[i]%13);
        }
        printf("\n");
    }
    return 0;
}
View Code

 

1077. Kuchiguse  ★

  Tips:

  1. 此题采用的是边输入边比较的方法,拿第一次输入的字符串依次和后面输入的字符串进行比较,left下标非递减.
  2. 因为读入的字符串可能带有空格,于是乎gets(common)连续执行了两次才去除了回车的麻烦.具体原因还没深究,标记下以后再来更新.
  3. 中间循环体加入了left<=rigth,这样如果前面有完全不匹配的字符串时,left就会赋值大于right,从而不再执行循环的内容.
  4. 相同代码用Java实现过,有一个点超时.所以在写题的时候,尽量用C/C++吧.
  
#include <stdio.h>
#include <string.h>

int main(int argc, const char * argv[]) {
    int n,i,j,k,left,right;
    char common[256],c[256];
    while(scanf("%d",&n) != EOF) {
        gets(common);
        gets(common);
        left = 0;
        right = strlen(common) - 1;
        for(i = 1;i < n;i++){
            gets(c);
            for(j = right,k = strlen(c) - 1;j >= left && k >= 0 && left <= right;j--,k--){
                if(common[j] != c[k]){
                    break;
                }
            }
            left = ++j;
        }
        if(left > right)
            printf("nai\n");
        else{
            for(i = left;i <= right;i++)
                printf("%c",common[i]);
            printf("\n");
        }
    }
    return 0;
}
View Code

 

1078. Hashing  ★★

  Tips:

  1. 说到此题真是略显辛酸.3月份做这题的时候犯过错,现在又犯了同样的错.务必看清题目啊,题目说的很清楚,用平方探测法处理冲突,怎么就是不长眼呢?
  2. 素数的计算.也挺久没遇到素数了,突然一下子忘了2是不是素数,然后想当然的认为它不是.以后碰到这种问题得好好思考思考,网上查查,确认之后再写.不然写到后面把前面的问题给忽略了,就会一直找不到错误在哪.
  3. C/C++的一些基本的原理还是没高清.给数组开辟新空间后如果没释放掉,后面再给它开辟新空间的话,可能会引用旧的地址空间,而且旧的数据也还在.而我继续想当然地认为new之后数组各位都为0.后来尝试过delete[],发现不起作用,于是用笨方法,每位设为0.
  4. 最后就是注意最后一个输出不要有空格.
  5. 心好累,慢慢捡起来吧.
  
#include <iostream>

int getPrime(int size){
    int i,k;
    if(size < 3)
        return 2;
    if(size == 3)
        return 3;
    while(true){
        k = size / 2;
        for(i = 2;i <= k;i ++){
            if(size % i == 0)
                break;
        }
        if(i > k)
            return size;
        ++size;
    }
}

int main() {
    int size,n,num,extra,i,j,k;
    int *hash,*loc;
    while(scanf("%d %d",&size,&n) != EOF) {
        if(n == 0)
            continue;
        size = getPrime(size);
        hash = new int[size];
        loc = new int[n];
        for(i = 0;i < size;i++)
            hash[i] = 0;
        for(i = 0;i < n;i++)
            loc[i] = 0;
        for(i = 0;i < n;i++){
            scanf("%d",&num);
            extra = num % size;
            for(j = extra,k = 0;k < size ;j = (extra + k * k) % size){
                if(hash[j] == 0) {
                    loc[i] = j;
                    hash[j] = 1;
                    break;
                }
                k++;
            }
            if(k >= size )
                loc[i] = -1;
        }
        printf("%d",loc[0]);
        for(i = 1;i < n;i++){
            if(loc[i] == -1)
                printf(" -");
            else
                printf(" %d",loc[i]);
        }
        printf("\n");
    }
    return 0;
}
View Code

 

1079. Total Sales of Supply Chain  ★

  Tips:

  1. 真是no zuo no die.说好的尽量用C来写,脑子一抽,又用Java来写了,最直接的方法,结果来了个超时.好吧,以为是算法问题,继续改,各种思路,仍得不到解决.换C++吧,还是各种思路,没能AC.最后想试试看用C++来写最开始的最直接的方法,呵呵,AC了...再说一遍,没什么事别用Java!!!
  2. 这题没什么技巧,也没什么陷阱,无非就先把输入的数据用二维数组保存起来,然后用到了队列.其它没什么好说的了.虽然是个25分的题,但我认为难度不大,只能给一星.
  
#include "iostream"
using namespace std;

int main(int argc, const char * argv[]) {
    int n,i,j,m,len,index;
    double p,r,amount;
    int **chain,*tree;
    double *price;
    while (scanf("%d %lf %lf",&n,&p,&r) != EOF) {
        chain = new int*[n];
        tree = new int[n];
        price = new double[n];
        price[0] = p;
        amount = 0.0;
        for(i = 0;i < n;i++){
            scanf("%d",&m);
            if(m == 0)
                len = 2;
            else
                len = m + 1;
            chain[i] = new int[len];
            chain[i][0] = m;
            for(j = 1;j < len;j++)
                scanf("%d",&chain[i][j]);
        }
        tree[0] = 0;
        for(i = 0,index = 1;i < n;i++){
            if(chain[tree[i]][0] == 0)
                amount += price[tree[i]] * chain[tree[i]][1];
            else{
                for(j = 1;j <= chain[tree[i]][0];j++){
                    tree[index++] = chain[tree[i]][j];
                    price[chain[tree[i]][j]] = price[tree[i]] * (1 + r / 100);
                }
            }
        }
        printf("%.1lf\n",amount);
    }
    return 0;
}
View Code

 

posted @ 2015-09-18 17:30  Thare  阅读(211)  评论(0编辑  收藏  举报