PAT-A:1001-1005总结

1001 - A+B Format (20)

这个题就是把一个数表示成标准形式,从右向左,每三位前加上一个逗号。但是黑窗口输出的时候是从左向右输出,所以我的解决办法就是通过取余把每个位上的数字保存下来,然后倒序输出。输出的时候计数器%3等于0的时候输出逗号。需要注意的是:

  1. 负数应该先输出一个负号;
  2. 计数器为0时虽然%3也为0,但此时不应该输出逗号;
  3. sum为0时,取余数取不到,应单独考虑。
#include <bits/stdc++.h>
using namespace std;
int main()
{
    int a, b, sum, cnt = 0;
    char str[101];
    cin >> a >> b;
    sum = a + b;
    if(sum == 0)
        cout << 0;
    if(sum < 0){
        cout << '-';
        sum = -sum;
    }
    while(sum != 0){
        str[cnt++] = char(sum%10 + 48);
        sum /= 10;
    }
    for(int i = cnt - 1; i >= 0; i--){
        cout << str[i];
        if(i%3 == 0 && i != 0)
            cout << ","; 
    }
    return 0;
} 

1002 - A+B for Polynomials (25)

这个题就是让求两个多项式的和,然后按指数递减输出。数学道理是:指数相同时,系数相加。最易想到的思路是把系数和指数建立一个结构体保存下来,但是这样在相加的时候会对其中一个多项式进行n次遍历,时间复杂度是平方级的。但题中说系数在[0, 1000]之内,所以创建一个容量为1001的数组,把索引当作指数就可以了。这样时间复杂度会是线性级的。

#include <bits/stdc++.h>
using namespace std;
int main()
{
    double p1[1010] = {0};
    double e2[1010] = {0};
    double c2[1010] = {0};
    int k, e, i, cnt = 0, t = 2;
    double c;
    while(t--){
        cin >> k;
        for(i = 0; i < k; i++){
            cin >> e >> c;
            p1[e] += c;
        }
    }
    for(i = 0; i < 1010; i++)
        if(p1[i] != 0.0){
            e2[cnt] = i;
            c2[cnt++] = p1[i];
        }
    cout << cnt;
    if(cnt != 0)
        cout << " ";
    for(i = cnt - 1; i >= 0; i--){
        printf("%.0f %.1f", e2[i], c2[i]);
        if(i != 0)
            cout << " ";
    }
    return 0;   
}

1003 - Emergency (25)

这个题是dijkstra的拓展应用。原生的迪杰斯特拉是最短路径,这个题是在边权最小的时候还需要点权最大,通过寻找的是这样的路有几条。更详细的dijkstra点击这里

#include <bits/stdc++.h>
#define INF 999999999
using namespace std;
class Dijkstra_Record{
    public:
        bool visited;
        int length;
        int num;
        int weight;
        Dijkstra_Record(){  visited = num = weight = 0; length = INF;} 
};
class MGraph{
    public:
        int **matrix;
        int vertexNum;
        int Dijkstra(int s, int v, MGraph *mg, int *weight, Dijkstra_Record *dr)
        {
            int n = mg->vertexNum, i, j;
            dr[s].num = 1;
            dr[s].length = 0;
            dr[s].weight = weight[s];
            for(i = 0; i < n; i++){
                int min = INF, cur = -1;
                for(j = 0; j < n; j++)
                    if(!dr[j].visited && dr[j].length < min)
                        min = dr[cur = j].length;
                if(cur == -1)
                    return -1;
                dr[cur].visited = true;
                for(j = 0; j < n; j++){
                    int newLen = dr[cur].length + mg->matrix[cur][j];           
                    if(!dr[j].visited && mg->matrix[cur][j] != INF ) 
                        if(newLen < dr[j].length){
                            dr[j].length = newLen;
                            dr[j].num = dr[cur].num;
                            dr[j].weight = dr[cur].weight + weight[j];
                        }else if(newLen == dr[j].length){
                            dr[j].num = dr[j].num + dr[cur].num;
                            if(dr[j].weight < dr[cur].weight + weight[j])
                                dr[j].weight = dr[cur].weight + weight[j];
                        }
                }
            }
        }
};
int main()
{
    int vertexNum, edgeNum, s, v, i, j;
    cin >> vertexNum >> edgeNum >> s >> v;
    int *weight = new int[vertexNum];
    for(i = 0; i < vertexNum; i++)
        cin >> weight[i];
    MGraph *mg = new MGraph();
    mg->vertexNum = vertexNum;
    mg->matrix = new int*[vertexNum];
    for(i = 0; i < vertexNum; i++){
        mg->matrix[i] = new int[vertexNum];
        fill(mg->matrix[i], mg->matrix[i] + vertexNum, INF);
    }
    int start, end, edgeWeight;
    for(i = 0; i < edgeNum; i++){
        cin >> start >> end >> edgeWeight;
        mg->matrix[start][end] = mg->matrix[end][start] = edgeWeight;
    }
    Dijkstra_Record *dr = new Dijkstra_Record[vertexNum];
    mg->Dijkstra(s, v, mg, weight, dr);
    cout << dr[v].num << " " << dr[v].weight;
    return 0;
}  

1004 - Counting Leaves (30)

这个题让计算每层的叶结点个数。输入的是:结点个数、非叶结点个数,每个非叶结点的孩子。规定01是跟结点。首先它是一棵普通的树,不是二叉树,不能用规范的形式来存储。把树按照图来存储是最好的选择。每行的行号是一个结点,每行里存储的是左右孩子。某行能到达但为空时说明它是叶结点,某行不能到达则无此结点。然后从根结点开始做深度周游,每次递归传入一个深度,若是叶结点,则记录此深度。

#include <bits/stdc++.h>
#define INF 999999999

using namespace std;
vector<int> matrix[101];
int record[101] = {0};
int deepest = -1;
void dfs(int index, int depth)
{
    if(matrix[index].size() == 0){
        record[depth]++;
        deepest = deepest>depth?deepest:depth;
        return;
    }
    for(int i = 0; i < matrix[index].size(); i++)
        dfs(matrix[index][i], depth+1);
}
int main()
{
    int n, m;       //树的节点,树的非叶节点 
    cin >> n >> m;
    int id, nn, i, j, temp;
    for(i = 0; i < m; i++){
        cin >> id >> nn;
        for(j = 0; j < nn; j++){
            cin >> temp;
            matrix[id].push_back(temp);
        }
    }
    dfs(1, 0);
    cout << record[0];
    for(i = 1; i <= deepest; i++)
        cout << " " << record[i];
    return 0;
}

1005 - Spell It Right (20)

很简单的一道题,直接求就行。

#include <bits/stdc++.h>
using namespace std;
int main()
{
    string words[] = {"zero", "one", "two", "three", "four", "five", 
                        "six", "seven", "eight", "nine"};
    char str[10100];
    cin >> str;
    int len = strlen(str);
    if(len == 1 && str[0] == '0')
        cout << "zero" << endl;
    int i, sum = 0, cnt = 0;
    for(i = 0; i < len; i++)
        sum = sum + int(str[i]) - 48;
    int arr[10100];
    while(sum != 0){
        arr[cnt++] = sum%10;
        sum /= 10;
    }
    for(i = cnt - 1; i >= 0; i--){
        cout << words[arr[i]];
        if(i != 0)
            cout << " ";
    }

    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_38206090/article/details/81607163