PAT (Basic Level) 乙组全题记录

前后12天,乙组的所有题目算是刷完了,总体感觉不太难,偶尔有一两道题卡了一会也是审题不清、特殊数据,或者一些逃不掉的坑,但收获依然不少,明白了“永远要用最大的恶意去揣测出题人”,也改掉不少坏习惯,甲组的题目寒假才有时间继续做了。2020.3月,PAT 干。

1001 害死人不偿命的(3n+1)猜想

#include 
using namespace std;

int main() {
    int n, cnt = 0;
    cin >> n;
    while (n != 1) {
        if (n & 1) n = 3 * n + 1;
        n = n / 2;
        cnt++;
    }
    printf("%d", cnt);
    return 0;
}

1002 写出这个数

#include 
#include 

using namespace std;

string map[10] = { "ling","yi","er","san","si","wu","liu","qi","ba","jiu"};

int main() {
#ifdef LOCAL
    fstream cin("data.in");
#endif // LOCAL
    int res = 0;
    char c;
    while (cin >> c) {
        res += c - '0';
    }
    stacks;
    
    while (res) {
        s.push(res % 10);
        res /= 10;
    }
    while (!s.empty()) {
        cout << map[s.top()];
        s.pop();
        if (!s.empty())
            cout << " ";
        
    }
    return 0;
}

 

1003 我要通过!

#include 
#include 
using namespace std;
int main() {
    int n, p = 0, t = 0;
    string s;
    cin >> n;
    for(int i = 0; i < n; i++) {
        cin >> s;
        map m;
        for(int j = 0; j < s.size(); j++) {
            m[s[j]]++;
            if (s[j] == 'P') p = j;
            if (s[j] == 'T') t = j;
        }
        if (m['P'] == 1 && m['A'] != 0 && m['T'] == 1 && m.size() == 3 && t-p != 1 && p * (t-p-1) == s.length()-t-1)
            printf("YES\n");
        else
            printf("NO\n");
    }
    return 0;
}

1004 成绩排名

#include 
#include 
using namespace std;

struct SS {
    string name, id;
    int grade;
    bool operator<(SS a) {
        return grade > a.grade;
    }
}stu[105];

int main() {
    int n;
    cin >> n;
    for (int i = 0; i < n; i++) {
        cin >> stu[i].name >> stu[i].id >> stu[i].grade;
    }
    sort(stu, stu + n);
    
    cout << stu[0].name << ' ' << stu[0].id << endl;
    cout << stu[n - 1].name << ' ' << stu[n - 1].id << endl;
    return 0;
}

1005 继续(3n+1)猜想

#include 
using namespace std;

int pre[10005];

int FIND(int x) {
    return x == pre[x] ? pre[x] : pre[x] = FIND(pre[x]);
}

void fun(int n) {
    if (n == 1)return ;
    if (n & 1) {
        pre[(3 * n + 1) / 2] = n;
        fun((3 * n + 1) / 2);
    }
        
    else {
        pre[n / 2] = n;
        fun(n / 2);
    }
        
}

int main() {
    int k;
    cin >> k;

    while (k--) {
        int n;
        cin >> n;
        if (!pre[n])
            pre[n] = n;
        fun(n);
    }
    int cnt = 0;
    for (int i = 100; i >= 1; i--) {
        if (pre[i] == i) {
            cnt++;
        }
    }
    for (int i = 100; i >= 1; i--) {
        if (pre[i] == i) {
            cout << i;
            cnt--;
            if (cnt != 0)cout << ' ';

        }
    }
    return 0;
}

1006 换个格式输出整数

#include 
#include 
using namespace std;

int main() {
    string s;
    cin >> s;
    if (s.size() == 3) {
        int len = s[0] - '0';
        for (int i = 0; i < len; i++) {
            putchar('B');
        }
    }
    if (s.size() >= 2) {
        int len = s[s.size() - 2] - '0';
        for (int i = 0; i < len; i++) {
            putchar('S');
        }
    }
    if (s.size() >= 1) {
        int len = s[s.size() - 1] - '0';
        for (int i = 1; i <= len; i++) {
            putchar(i + '0');
        }
    }
    return 0;
}

1007 素数对猜想

#include 
#include 
using namespace std;

bool M[100005];
int prime[50005];
int total;
void Eulersieve(int n) {
    for (int i = 2; i <= n; i++) {
        if (!M[i])  prime[total++] = i;
        for (int j = 0; j < total && i * prime[j] <= n; j++) {
                M[i * prime[j]] = true;
                if (i % prime[j] == 0)break;
            }
        
    }
}

int main() {
    int n, res = 0;
    cin >> n;
    Eulersieve(n);

    for (int i = 1; i < total; i++) {
        if (prime[i] - prime[i - 1] == 2) {
            res++;
        }
    }
    printf("%d\n", res);
    return 0;
}

1008 数组元素循环右移问题

#include 
#include 
using namespace std;

int arr[105];

int main() {
    int n, m;
    cin >> n >> m;
    for (int i = 0; i < n; i++) {
        scanf("%d", &arr[i]);
    }

    int k = (n - m) % n;
    while (k < 0) {
        k += n;
    }
    printf("%d", arr[k]);
    k = (k + 1) % n;
    for (int i = 0; i < n - 1; i++) {
        printf(" %d", arr[k]);
        k = (k + 1) % n;
    }
    return 0;
}

1009 说反话

#include 
#include 
#include 
#include 
using namespace std;

int main() {
    string s;
    stackq;
    while (cin >> s) {
        q.push(s);
        if (getchar() == '\n')break;
    }
    while (!q.empty()) {
        cout << q.top();
        q.pop();
        if (!q.empty())cout << ' ';
        
    }
    return 0;
}

1010 一元多项式求导

#include
using namespace std;
int main(){
    int coef;
    int expo;
    cin >> coef >> expo;
    if (expo == 0){
        cout << "0 0";
        return 0;
    }
    else
        cout << coef * expo << ' ' << expo - 1;
    while (cin >> coef >> expo)
        if (expo != 0)
            cout << ' ' << coef * expo << ' ' << expo - 1;
    return 0;
}

1011 A+B 和 C

#include 
#include 
#include 
using namespace std;

int main() {
    int T;
    cin >> T;
    for (int i = 1; i <= T; i++) {
        long long a, b, c;
        cin >> a >> b >> c;
        bool res = (a + b > c);
        cout <

1012 数字分类

#include 
#include 
using namespace std;

int arr[1005];

int a[6];

int main() {
    int n;
    cin >> n;
    for (int i = 0; i < n; i++) {
        scanf("%d", &arr[i]);
    }
    int flag = 1, cnt = 0;
    bool a2_flag = false;
    for (int i = 0; i < n; i++) {
        if (arr[i] % 5 == 0 && !(arr[i] & 1)) {
            a[1] += arr[i];
        }
        else if (arr[i] % 5 == 1) {
            a[2] += flag * arr[i];
            flag = ~flag + 1;
            a2_flag = true;
        }
        else if (arr[i] % 5 == 2) {
            a[3]++;
        }
        else if (arr[i] % 5 == 3) {
            a[4] += arr[i];
            cnt++;
        }
        else if (arr[i] % 5 == 4) { //错误点,最后直接写了else
            if (arr[i] > a[5])a[5] = arr[i];
        }
    }
    if (a[1]) {
        printf("%d", a[1]);
    }
    else
        printf("N");
    for (int i = 2; i <= 5; i++) {
        if ((i != 2 && !a[i]) || (i == 2 && !a2_flag)) {
            printf(" N");
        }
        else {
            if (i == 4) {
                printf(" %.1lf", (double)a[i] / cnt);
            }
            else printf(" %d", a[i]);
        }
    }
    return 0;
}

1013 数素数

#include 
#include 

using namespace std;
const int N = 200005;
bool M[N];
int prime[10005];
int total;
void EulerSieve() {
    for (int i = 2; i < N && total < 10005; i++) {
        if (!M[i]) {
            prime[total++] = i;
        }
        for (int j = 0; j < total && i * prime[j] < N; j++) {
            M[i * prime[j]] = true;
            if (i % prime[j] == 0)break;
        }
    }
}

int main() {
    EulerSieve();

    int m, n;
    cin >> m >> n;
    m--; n--;
    int k = 0;
    for (int i = m; i <= n; i++) {
        printf("%d", prime[i]);
        k++;
        
        if (k % 10 == 0) {
            printf("\n");
            continue;
        }
        if (i != n)printf(" ");
    }
    return 0;
}

1014 福尔摩斯的约会

#include 
#include 
#include 
#include 
using namespace std;

string DAY[8] = { "","MON","TUE","WED","THU","FRI","SAT","SUN" };

int alphabet_judge(char c) {
    if (c >= 'a' && c <= 'z')return 1;
    if (c >= 'A' && c <= 'Z')return 2;
    return 0;
}

bool check1(char c) {
    if (c >= 'A' && c <= 'G')return true;
    return false;
}
bool check2(char c) {
    if ((c >= '0' && c <= '9') || (c >= 'A' && c <= 'N'))return true;
    return false;
}
int main() {
    string s1, s2, s3, s4;
    cin >> s1 >> s2 >> s3 >> s4;
    string day;
    int hours, minute;
    int len = s1.length() < s2.length() ? s1.length() : s2.length();
    int i;

    for (i = 0; i < len; i++) {
        if (check1(s1[i]) && s1[i] == s2[i]) {
            day = DAY[s1[i] - 'A' + 1];
            i++;
            break;
        }
    }

    for (; i < len; i++) {
        if (check2(s1[i]) && s1[i] == s2[i]) {
            hours = (s1[i] >= '0' && s1[i] <= '9') ? s1[i] - '0' : 10 +s1[i] - 'A';
            break;
        }
    }
    len = s3.length() < s4.length() ? s3.length() : s4.length();
    for (i = 0; i < len; i++) {
        if (alphabet_judge(s3[i]) && s3[i] == s4[i]) {
            minute = i;
            break;
        }
    }
    cout << day << ' ';
    printf("%02d:%02d", hours, minute);
    return 0;
}

1015 德才论

#include 
#include 
#include 
using namespace std;

struct stu {
    int id, moral, talent;
    bool operator<(stu s)const {
        if (moral + talent == s.moral + s.talent) {
            if (moral == s.moral) {
                return id > s.id;
            }
            return moral < s.moral;
        }
        return moral + talent < s.moral + s.talent;
    }
};
priority_queueq1, q2, q3, q4;

inline void print(priority_queueq) {
    while (!q.empty()) {
        stu s = q.top();
        q.pop();
        printf("%d %d %d\n", s.id, s.moral, s.talent);
    }

}
int main() {
    int n, least, standard;
    cin >> n >> least >> standard;
    for (int i = 0; i < n; i++) {
        stu s;
        scanf("%d%d%d", &s.id, &s.moral, &s.talent);
        if (s.moral >= least && s.talent >= least) {
            if (s.moral >= standard && s.talent >= standard) {
                q1.push(s);
            }
            else if (s.moral >= standard && s.talent < standard) {
                q2.push(s);
            }
            else if (s.moral < standard && s.talent < standard && s.moral >= s.talent) {
                q3.push(s);
            }
            else {
                q4.push(s);
            }
        }
    }
    printf("%d\n", q1.size() + q2.size() + q3.size() + q4.size());
    print(q1);
    print(q2);
    print(q3);
    print(q4);
    return 0;
}

1016 部分A+B

#include 
using namespace std;

long long getP(int a,int da) {
    long long pa = 0;
    while (a) {
        if (a % 10 == da) {
            pa += da;
            pa *= 10;
        }
        a /= 10;
    }
    pa /= 10;
    return pa;
}


int main() {
    
    int a, da, b, db;
    scanf("%d%d%d%d", &a, &da, &b, &db);
    printf("%lld", getP(a, da) + getP(b, db));
    return 0;
}

1017 A除以B

#include 
#include 
#include 
using namespace std;

vectorres;
string a;
int x, b;

int main() {
    cin >> a >> b;
    int i = 0, temp;
    while ((temp = ((x << 3) + (x << 1) + (a[i] ^ 48))) / b == 0) {
        x = temp;
        i++;
    }
    for (; i < a.size(); i++) {
        x = (x << 3) + (x << 1) + (a[i] ^ 48);//x累计数字来进行除法计
        res.push_back(x / b);//存放结果
        x %= b;//除完后的余数
    }
    if (res.empty()) 
        res.push_back(0);
    for (i = 0; i < res.size(); i++) {
        cout << res[i];//输出
    }
    cout << ' ';
    cout << x << endl;
    return 0;
}

1018 锤子剪刀布

#include 
#include 
#include 
#include 
#include 
#include 
using namespace std;

int A, B, C;//甲胜、乙胜、平局
int M_A[3], M_B[3];

int judge(char a,char b) {
    switch (a) {
    case 'C':
        if (b == 'C') return 0;
        if (b == 'B') return 1; 
        return -1;
    case 'B':
        if (b == 'B')return 0;
        if (b == 'J')return 1;
        return -1;
    case 'J':
        if (b == 'J')return 0;
        if (b == 'C')return 1;
        return -1;
    }
}
int getIndex(char c) {
    if (c == 'B')return 0;
    if (c == 'C')return 1;
    return 2;
}
char getLetter(int i) {
    if (i == 0)return 'B';
    if (i == 1)return 'C';
    return 'J';
}
int main() {
    int n;
    cin >> n;
    cin.ignore();
    for (int i = 0; i < n; i++) {
        char a, b;
        a = getchar(); getchar();
        b = getchar(); getchar();

        int temp = judge(a, b);
        if (temp == -1) {
            A++;
            M_A[getIndex(a)]++;
        }
        else if (temp == 1) {
            B++;
            M_B[getIndex(b)]++;
        }
        else C++;
    }

    printf("%d %d %d\n", A, C, n - A - C);
    printf("%d %d %d\n", B, C, n - B - C);
    
    int index_a = 0, index_b = 0;
    for (int i = 1; i < 3; i++) {
        if (M_A[i] > M_A[index_a]) {
            index_a = i;
        }
        if (M_B[i] > M_B[index_b]) {
            index_b = i;
        }
    }
    printf("%c %c", getLetter(index_a), getLetter(index_b));
    return 0;
}

1019 数字黑洞

#include 
#include 
#include 
#include 
using namespace std;

int getMin(int x) {
    int flag[10] = { 0 };
    for (int i = 0; i < 4; i++) {
        flag[x % 10] ++;
        x /= 10;
    }
    int res = 0;
    for (int i = 0; i < 10; i++) {
        while (flag[i]) {
            flag[i]--;
            res = res * 10 + i;
        }
    }
    return res;
}

int getMax(int x) {
    int flag[10] = { 0 };
    for (int i = 0; i < 4; i++) {
        flag[x % 10] ++;
        x /= 10;
    }
    int res = 0;
    for (int i = 9; i >= 0; i--) {
        while (flag[i]) {
            flag[i]--;
            res = res * 10 + i;
        }
    }
    return res;
}
int main() {
    int n;
    cin >> n;
    int flag[10] = { 0 };
    int temp = n;
    while (temp) {
        flag[temp % 10]++;
        if (flag[temp % 10] == 4) {
            printf("%04d - %04d = 0000\n", n, n);
            return 0;
        }
        temp /= 10;
    }
    int L, R;
    do {
        L = getMax(n), R = getMin(n);
        n = L - R;
        printf("%04d - %04d = %04d\n", L, R, n);
    } while (L - R != 6174);
    return 0;
}

1020 月饼

#include 
#include 
#include 
#include 
#include 

using namespace std;
struct node {
    double value, weight;
    bool operator<(node a) {
        return value / weight > a.value / a.weight;
    }
}N[1005];

int main(){
    int n;
    double V, res = 0;
    cin >> n >> V;
    for (int i = 0; i < n; i++) {
        scanf("%lf", &N[i].weight);
    }
    for (int i = 0; i < n; i++) {
        scanf("%lf", &N[i].value);
    }
    sort(N, N + n);

    int i;
    for (i = 0; i < n && V - N[i].weight >= 0; i++) {
        res += N[i].value;
        V -= N[i].weight;
    }
    if (i != n && V > 0) {
        res += N[i].value * (V / N[i].weight);
    }
    printf("%.2lf", res);
    return 0;
}

1021 个位数统计

#include 
using namespace std;

int res[10];
int main() {
    char c;
    while ((c = getchar()) != '\n') {
        res[c - '0']++;
    }
    for (int i = 0; i < 10; i++) {
        if (res[i] != 0)
        printf("%d:%d\n", i, res[i]);
    }
    return 0;
}

1022 D进制的A+B

#include 
#include 
using namespace std;

int res[35];

int main() {
    int a, b, n, D;
    scanf("%d%d%d", &a, &b, &D);
    n = a + b;
    if (n == 0) {
        printf("0");
    }
    else {
        int i = 0;
        while (n) {
            res[i++] = n % D;
            n /= D;
        }
        i--;
        for (; i >= 0; i--) {
            printf("%d", res[i]);
        }
    }
    
    printf("\n");
    return 0;
}

1023 组个最小数

#include 
using namespace std;

int cnt[10];

int main() {
    int k;  
    for (int i = 0; i < 10; i++) {
        scanf("%d", &k);
        cnt[i] = k;
    }
    for (int i = 1; i < 10; i++) {
        if (cnt[i]) {
            putchar(i + '0');
            cnt[i]--;
            break;
        }
    }
    for (int i = 0; i < 10; i++) {
        while (cnt[i]) {
            putchar(i + '0');
            cnt[i]--;
        }
    }
    return 0;
}

1024 科学计数法

#include 
#include 
#include 
#include 
#include 
#include 
using namespace std;


int e;//指数
string fraction;//定点部分

int main() {
    string s;
    cin >> s;
    char sign1 = s[0];
    int i = 1;
    for (i = 1; s[i] != 'E'; i++) {
        if (s[i] != '.') {
            fraction.append(1, s[i]);
        }
    }
    char sign2 = s[++i];
    i++;
    for (; i < s.length(); i++) {
        e = (e << 3) + (e << 1) + (s[i] ^ 48);
    }

    if (sign1 == '-')
        putchar(sign1);

    if (e == 0) {
        putchar(fraction[0]);
        putchar('.');
        cout << fraction.substr(1);
        return 0;
    }
    
    if (sign2 == '-') {
        putchar('0');putchar('.');
        for (int i = 0; i < e - 1; i++) {
            putchar('0');
        }
        cout << fraction << endl;
    }
    else {
        if (e >= fraction.length() - 1) {
            cout << fraction;
            for (int i = 0; i < e - fraction.length() + 1; i++) {
                putchar('0');
            }
        }
        else {
            for (int i = 0; i < fraction.length(); i++) {
                putchar(fraction[i]);
                if (i == e) {
                    putchar('.');
                }
            }
        }
    }
    return 0;
}

1025 反转链表

地址只有5位数,正解是用静态链表,可以不建链表,就想练习一下,这样写起来真挺麻烦的。

永远要用最恶意的方式去揣测出题人,输入数据中可能会有不存在这条链表的结点。

#include 
#include 
#include 
#include 
using namespace std;

struct node {
    node* next = NULL;
    int address, data, to;
    void push_back(node* p) {
        next = p;
        p->next = NULL;
    }
};
mapM;

node* reverse_k(node* p, int k) {
    node* head = p;
    node* pre = NULL;
    node* next = p->next;
    int i = 1;
    while (i < k) {
        pre = p;
        p = next;
        next = p->next;
        p->next = pre;
        i++;
    }
    head->next = next;
    return p;
}

int main() {
    int head, n, k;
    cin >> head >> n >> k;
    for (int i = 0; i < n; i++) {
        node p;
        scanf("%d%d%d", &p.address, &p.data, &p.to);
        M[p.address] = p;
    }
    int p = head;
    node* root = new node();
    node* pp = root;
    int cnt = 0;
    while (p != -1) {
        pp->push_back(&M[p]);
        pp = pp->next;
        p = M[p].to;
        cnt++;
    }
    pp = root->next;
    node* pre = root;
    while (cnt - k >= 0) {
        pp = reverse_k(pp, k);
        pre->next = pp;
        for (int i = 0; i < k; i++) {
            pre = pp;
            pp = pp->next;
        }
        cnt -= k;
    }
    pp = root->next;
    while (pp->next) {
        printf("%05d %d %05d\n", pp->address, pp->data, pp->next->address);
        pp = pp->next;
    }
    printf("%05d %d %d", pp->address, pp->data, -1);
    return 0;
}

看下大佬的思路,还是很有益处的。

#include 
#include 
#include 
using namespace std;

int Data[100005], Next[100005], List[100005];
int main() {
    int first, n, k;
    cin >> first >> n >> k;
    int temp;
    for (int i = 0; i < n; i++) {
        cin >> temp;
        cin >> Data[temp] >> Next[temp];
    }
    int sum = 0;
    while (first != -1) {
        List[sum++] = first;
        first = Next[first];
    }
    
    for (int i = 0; i + k - 1 < sum; i += k) {
        //左开右闭
        reverse(List + i, List + i + k);
    }
    for (int i = 0; i < sum - 1; i++) {
        printf("%05d %d %05d\n", List[i], Data[List[i]], List[i + 1]);
    }
    printf("%05d %d -1", List[sum - 1], Data[List[sum - 1]]);
}

1026 程序运行时间

10^7,啥也不用考虑,一秒一秒加就是了,也不会错。用最快的速度,写跑最慢的代码。

#include 
#include 
using namespace std;

int hours, minutes, seconds;

int main() {
    double c1, c2;
    cin >> c1 >> c2;
    int n = round((c2 / 100) - (c1 / 100)) + 0.1;//避免精度出现误差
    for (int i = 0; i < n; i++) {
        seconds++;
        if (seconds == 60) {
            seconds = 0;
            minutes++;
            if (minutes == 60) {
                minutes = 0;
                hours++;
            }
        }
    }
    printf("%02d:%02d:%02d", hours, minutes, seconds);
    return 0;
}

1027 打印沙漏

毒瘤,后面不打空格,也不说。

#include 
#include 
using namespace std;

int layer[50];

void print(char c, int k) {
    while (k--) {
        putchar(c);
    }
}
int main() {
    layer[1] = 1;
    for (int i = 2, j = 3; layer[i - 1] <= 1000; i++, j += 2) {
        layer[i] = 2 * j + layer[i - 1];
    }
    int n; char c;
    scanf("%d %c", &n, &c);
    int k = 1;
    while (n >= layer[k + 1])
        k++;
    int i = 2 * k - 1, j = 0;
    for (; i > 1; i -= 2, j++) {
        print(' ', j);
        print(c, i);
        //print(' ', j);
        putchar('\n');
    }
    for (; i <= 2 * k - 1; i += 2, j--) {
        print(' ', j);
        print(c, i);
        //print(' ', j);
        putchar('\n');
    }
    printf("%d", n - layer[k]);
    return 0;
}

1028 人口普查

请永远用最恶意的方式去揣测出题人

#include 
#include 
using namespace std;
string LOW = "1814/09/06", HIGH = "2014/09/06";
bool Is_rational(string& s) {
    if (s.compare(LOW) >= 0 && s.compare(HIGH) <= 0)return true;
    return false;
}
int main() {
    int n, cnt = 0;
    cin >> n;
    string oldest_name, youngest_name, oldest_bir = HIGH, youngest_bir = LOW;
    for (int i = 0; i < n; i++) {
        string name, bir;
        cin >> name >> bir;
        if (Is_rational(bir)) {
            cnt++;
            if (bir.compare(oldest_bir) <= 0) {
                oldest_bir = bir;
                oldest_name = name;
            }
            if (bir.compare(youngest_bir) >= 0) {
                youngest_bir = bir;
                youngest_name = name;
            }
        }
    }
    if (cnt > 0) {
        cout << cnt << ' ' << oldest_name << ' ' << youngest_name << endl;;
    }
    else cout << 0 << endl; 
    return 0;
}

1029 旧键盘

前面被坑了几题,紧张过度了。。。。我以为输出要用空格把下划线换回来。

#include 
#include 
using namespace std;
bool flag[257];
int main() {
    queueq1, q2;
    char c;
    while ((c = getchar()) != '\n') {
        if (c >= 'a' && c <= 'z')c -= 32;
        //if (c == '_')c = ' ';
        q1.push(c);
    }
    while ((c = getchar()) != '\n') {
        if (c >= 'a' && c <= 'z')c -= 32;
        //if (c == '_')c = ' ';
        q2.push(c);
    }
    while (!q1.empty() && !q2.empty()) {
        char c1 = q1.front(), c2 = q2.front();
        if (c1 == c2) {
            q1.pop(); q2.pop();
        }
        else {
            if (!flag[c1]) {
                flag[c1] = true;
                putchar(c1);
            }
            q1.pop();
        }
    }

    while (!q1.empty()) {
        char c1 = q1.front();
        if (!flag[c1]) {
            flag[c1] = true;
            putchar(c1);
        }
        q1.pop();
    }
    return 0;
}

1030 完美数列

寻找以 \(i (0 \leqslant i\leqslant n-1)\)为起点的数列长度,找最大值。硬搜的话会超时,二分的思想。

类似二分搜索,如果 arr[i]*p < arr[mid] ,则要找的答案一定 l ~ mid - 1 里面。

如果 arr[i]*p>=arr[mid] 的话,mid 可能是答案,所以是 mid ~ r

假如 l=7, r=8, mid=7,进入B_search(i, mid, r) ,还是l=7, r=8, mid=7,所以边界要扩展到两个元素, return arr[i] * p >= arr[r] ? r : l;。(测试数据 i=1 时就会出现这种情况)。

#include 
#include 
using namespace std;

long long arr[100005];
int res, p;
int B_search(int i,int l,int r) {
    if (r - l <= 1) {
        if (l == r)
            return l;
        return arr[i] * p >= arr[r] ? r : l;
    }
    int mid = (l + r) / 2;
    if (arr[i] * p < arr[mid])
        return B_search(i, l, mid - 1);
    else {
        return B_search(i, mid, r);
    }
}
int main() {
    int n;
    scanf("%d%d", &n, &p);
    for (int i = 0; i < n; i++) {
        scanf("%d", &arr[i]);
    }
    sort(arr, arr + n);
    for (int i = 0; i < n; i++) {
        int j = B_search(i, i, n - 1);
        if (j - i + 1 > res)
            res = j - i + 1;
    }

    cout << res;
    return 0;
}

1031 查验身份证

#include 
#include 
#include 
#include 
using namespace std;

int weight[17] = { 7,9,10,5,8,4,2,1,6,3,7,9,10,5,8,4,2 };
char M[11] = { '1', '0', 'X', '9', '8', '7', '6', '5' ,'4', '3', '2' };
int calc(string s) {
    int res = 0;
    for (int i = 0; i < 17; i++) {
        res += (s[i] ^ 48) * weight[i];
    }
    return res % 11;
}

int main() {
    int n;
    cin >> n;
    bool flag = true;
    for (int i = 0; i < n; i++) {
        string s;
        cin >> s;
        int k = calc(s);
        if (M[k] != s[17]) {
            cout << s << endl;
            flag = false;
        }
    }
    if (flag) {
        cout << "All passed";
    }
    
    return 0;
}

1032 挖掘机技术哪家强

#include 
#include 
using namespace std;

int grade[100005];

int main(){
    int N;
    int c1, c2;
    scanf("%d", &N);
    for (int i = 0; i < N; i++) {
        scanf("%d%d", &c1, &c2);
        grade[c1] += c2;
    }
    int res = 0, index = 0;
    for (int i = 1; i <= N; i++) {
        if (grade[i] > res) {
            res = grade[i];
            index = i;
        }
    }
    cout << index << " " << res << endl;
    return 0;
}

1033 旧键盘打字

理解能力出现了危机,题目如下:

输入在 2 行中分别给出坏掉的那些键、以及应该输入的文字。其中对应英文字母的坏键以大写给出;每段文字是不超过 105 个字符的串。可用的字符包括字母 [a-z, A-Z]、数字 0-9、以及下划线 _(代表空格)、,.-+(代表上档键)。题目保证第 2 行输入的文字串非空。

我起初以为 ,.-+ 四个符号都代表上档键。。。

cin不能接收空串,要用getline。

#include 
#include 
#include 
#include 
using namespace std;

bool flag1[257];

int main() {
    string s1, s2;
    //cin >> s1 >> s2;
    getline(cin, s1);
    getline(cin, s2);
    bool flag = false;
    for (int i = 0; i < s1.length(); i++) {
        char c = s1[i];
        if (c == '+') {
            flag = true;
        }
        flag1[c] = true;
    }
    
    for (int i = 0; i < s2.length(); i++) {
        if (s2[i] >= 'A' && s2[i] <= 'Z' && flag)continue;
        char c = s2[i];
        if (c >= 'a' && c <= 'z')
            c -= 32;
        if (!flag1[c]) {    
            putchar(s2[i]);
        }
    }
    cout << endl;
    return 0;
}

1034 有理数四则运算

偷个懒,分式运算没什么东西,这题就是纯麻烦,不写了。

#include 
#include 
using namespace std;

long gcd(long a, long b){
    if(b==0) return a;
    else return gcd(b,a%b);
}
void printfrac(long n, long d)
{
    if(d == 0) { printf("Inf"); return; }
    int inegative = 1; 
    if(n < 0) { n = -n; inegative *= -1; }
    if(d < 0) { d = -d; inegative *= -1; }
    long gcdd = gcd(n,d);           
    n /= gcdd;
    d /= gcdd;
    if(inegative == -1)  printf("(-");
    if(n / d && n % d)   printf("%ld %ld/%ld", n / d, n % d, d); 
    else if(n % d)       printf("%ld/%ld", n % d, d);            
    else                 printf("%ld", n / d);
    if(inegative == -1)  printf(")");
}
int main()
{
    long a1, b1, a2, b2;
    scanf("%ld/%ld %ld/%ld", &a1, &b1, &a2, &b2);
    char op[4] = {'+', '-', '*', '/'};
    for(int i = 0; i < 4; i++)
    {
        printfrac(a1, b1);        printf(" %c ", op[i]);
        printfrac(a2, b2);        printf(" = ");
        switch(op[i])
        {
            case '+': printfrac(a1 * b2 + a2 * b1, b1 * b2); break;
            case '-': printfrac(a1 * b2 - a2 * b1, b1 * b2); break;
            case '*': printfrac(a1 * a2,           b1 * b2); break;
            case '/': printfrac(a1 * b2,           b1 * a2); break;
        }
        printf("\n");
    }
    return 0;
}

1035 插入与归并

这题考察点很怪,打着归并排序的名号,其实数据里的排序顺序完全不是我们平常意义上写的归并排序能够得到的。

我们正常情况下,递归写归并排序,都是把左半部分完全排完,再排右半部分。得不到从左往右一轮一轮的,只能借助Sort来模仿一下了。

#include 
#include 
#include 
using namespace std;
int main() {
    int n, a[100], b[100], i, j;
    cin >> n;
    for (int i = 0; i < n; i++)
        cin >> a[i];
    for (int i = 0; i < n; i++)
        cin >> b[i];
    //如果前i个都已经有序,并且第i+1到第n个还是初始的样子,则是插入排序
    for (i = 0; i < n - 1 && b[i] <= b[i + 1]; i++);
    for (j = i + 1; a[j] == b[j] && j < n; j++);
    if (j == n) {
        cout << "Insertion Sort" << endl;
        sort(a, a + i + 2);//要排下标为0到a+i+1的元素
    }
    else {
        cout << "Merge Sort" << endl;
        int k = 1, flag = 1;
        while (flag) {
            flag = 0;
            for (i = 0; i < n; i++) {
                if (a[i] != b[i])
                    flag = 1;
            }
            k = k * 2;
            for (i = 0; i < n / k; i++)
                sort(a + i * k, a + (i + 1) * k);
        }
        //排可能剩下的部分
        sort(a + n / k * k, a + n);
    }
    for (j = 0; j < n; j++) {
        if (j != 0) printf(" ");
        printf("%d", a[j]);
    }
    return 0;
}

1036 跟奥巴马一起编程

#include 
#include 
using namespace std;

int grade[100005];

int main(){
    int row, col, n;
    char c;
    scanf("%d%c%c", &n, &c, &c);
    row = n / 2; col = n;
    if (n & 1) {
        row++;
    }
    for (int j = 0; j < col; j++) {
        printf("%c", c);
    }
    printf("\n");

    for (int i = 1; i < row - 1; i++) {
        printf("%c", c);
        for (int j = 1; j < col - 1; j++) {
            printf(" ");
        }
        printf("%c", c);
        printf("\n");
    }

    for (int j = 0; j < col; j++) {
        printf("%c", c);
    }
    printf("\n");
    return 0;
}

1037 在霍格沃茨找零钱

#include 
using namespace std;

int main() {
    
    int sum1 = 0, sum2 = 0;
    int p1, p2, p3;
    scanf("%d.%d.%d", &p1, &p2, &p3);
    sum1 = p3 + p2 * 29 + p1 * 17 * 29;
    
    scanf("%d.%d.%d", &p1, &p2, &p3);
    sum2 = p3 + p2 * 29 + p1 * 17 * 29;

    int res = sum2 - sum1;
    p1 = res / (29 * 17);
    res %= (29 * 17);
    p2 = res / 29;
    res %= 29;
    if (p1 < 0) {
        p2 = ~p2 + 1;
        res = ~res + 1;
    }
    printf("%d.%d.%d", p1, p2, res);
    return 0;
}

1038 统计同成绩学生

cin 超时

#include 
#include 
#include 
using namespace std;

int score[101];

int main() {
    int n, c1;
    cin >> n;
    for (int i = 0; i < n; i++) {
        //cin >> c1;
        scanf("%d", &c1);
        score[c1]++;
    }
    int k;
    cin >> k;
    for (int i = 0; i < k; i++) {
        scanf("%d", &c1);
        printf("%d", score[c1]);
        if (i != k - 1)putchar(' ');
    }
    return 0;
}

1039 到底买不买

#include 
using namespace std;

int s1[256], s2[256];
bool flag = false;
int offset1, offset2;
int main() {
    char c;
    while ((c = getchar()) != '\n') {
        s1[c]++;
    }
    while ((c = getchar()) != '\n') {
        s2[c]++;
    }
    for (int i = 0; i < 256; i++) {
        if (s2[i] > s1[i]) {
            flag = true;
            offset2 += s2[i] - s1[i];
        }
        else {
            offset1 += s1[i] - s2[i];
        }
    }
    if (flag) {
        printf("No %d", offset2);
    }
    else {
        printf("Yes %d", offset1);
    }
    return 0;
}

1040 有几个PAT

#include 
#include 
#include 
#include 
using namespace std;

//vectorP_cnt, T_cnt;
int cnt_p[100005];
char str[100005];
int main() {
    int n = 0;
    while ((str[n++] = getchar()) != '\n');
    str[--n] = 0;   
    cnt_p[0] = str[0] == 'P' ? 1 : 0;
    for (int i = 1; i < n; i++) {
        cnt_p[i] = cnt_p[i - 1];
        if (str[i] == 'P') {
            cnt_p[i]++;
        }
    }

    int temp = 0;
    int mod = 1000000007;
    long long res = 0;
    for (int i = n - 1; i >= 0; i--) {
        if (str[i] == 'T') {
            temp++;
        }
        else if (str[i] == 'A') {
            res = res + (temp * 1ll * cnt_p[i]) % mod;
        }
    }
    printf("%lld", res % mod);
}

1041 考试座位号

#include 
#include 
#include 
using namespace std;

string l[1005];
int n, m[1005], r[1005];

int main() {
    cin >> n;
    int i = 0;
    while (n--) {
        cin >> l[i];
        int c;
        scanf("%d%d", &c, &r[i]);
        m[c] = i;
        i++;
    }
    int k;
    cin >> k;
    while (k--) {
        int c;
        cin >> c;
        int j = m[c];
        cout << l[j] << ' ';
        printf("%d\n", r[j]);
    }
    return 0;
}

1042 字符统计

#include 
#include 
using namespace std;

int cnt[257];
int res = 0;
int main() {
    char c;
    while ((c = getchar()) != '\n') {
        if (c >= 'A' && c <= 'Z') c += 32;
        cnt[c]++;
    }
    for (int i = 'z'; i >= 'a'; i--) {
        if (cnt[i] >= res) {
            res = cnt[i];
            c = i;
        }
    }
    putchar(c);
    printf(" %d", res);
    return 0;
}

1043 输出PATest

#include 
#include 
using namespace std;

int cnt[256];

void pp(char c,int &a) {
        putchar(c);
        a--;    
}

//PATest 
int main() {
    char c;
    while ((c = getchar()) != '\n') {
        cnt[c]++;
    }
    int P = cnt['P'], A = cnt['A'], T = cnt['T'], e = cnt['e'], s = cnt['s'], t = cnt['t'];
    while (P || A || T || e || s || t) {
        if (P)pp('P', P);
        if (A)pp('A', A);
        if (T)pp('T', T);
        if (e)pp('e', e);
        if (s)pp('s', s);
        if (t)pp('t', t);
    }
    return 0;
}

1044 火星数字

#include 
#include 
#include 
#include 
using namespace std;

int strToint(string s, int n) {
    int res = 0;
    for (int i = 0; i < n; i++) {
        res = (res << 1) + (res << 3) + (s[i] ^ 48);
    }
    return res;
}

char str[100];
string low[13] = { "tret" ,"jan", "feb", "mar", "apr", "may", "jun", "jly", "aug", "sep", "oct", "nov", "dec" };
string high[13] = { "","tam", "hel", "maa", "huh", "tou", "kes", "hei", "elo", "syy", "lok", "mer", "jou" };

int Find(string s) {
    for (int i = 0; i < 13; i++) {
        if (s.compare(low[i]) == 0)return i;
    }
    for (int i = 1; i < 13; i++) {
        if (s.compare(high[i]) == 0)return i * 13;
    }
}

int main() {
    int N;
    cin >> N;
    cin.ignore();
    while (N--) {
        string str;
        getline(cin, str);
        if (str[0] >= '0' && str[0] <= '9') {
            int k = strToint(str, str.length());
            if (k == 0) {
                cout << "tret" << endl;
                continue;
            }
            int c1 = k % 13;
            k /= 13;
            int c2 = k % 13;
            if (c2 > 0) {
                cout << high[c2];
                if (c1 > 0)cout << ' ';
            }
            if (c1 > 0)
                cout << low[c1];
            cout << endl;
        }
        else {
            int temp = 0, res = 0;
            if ((temp = str.find(' ')) != string::npos) {
                res += Find(str.substr(0, temp));
                str = str.substr(temp + 1);
            }
            res += Find(str);
            cout << res << endl;
        }
    }
    return 0;
}

1045 快速排序

#include 
#include 
#include 
#include 
using namespace std;

int arr[100005];
int big[100005];//存储每个元素前面是否有比它大的元素,有则存最大值,无则存0
int small[100005];//同上
int main() {
    int n;
    cin >> n;
    for (int i = 0; i < n; i++) {
        scanf("%d", &arr[i]);
    }
    int MAX = 0;
    for (int i = 0; i < n; i++) {
        if (arr[i] > MAX)
            MAX = arr[i];
        else 
            big[i] = MAX;
    }

    int MIN = 1 << 30, cnt = 0;
    for (int i = n - 1; i >= 0; i--) {
        if (arr[i] < MIN) {
            if (!big[i])cnt++;
            MIN = arr[i];
        }
        else
            small[i] = MIN;
    }
    int i = 0;
    printf("%d\n", cnt);
    for (; i < n; i++) {
        if (!big[i] && !small[i]) {
            printf("%d", arr[i]);
            i++;
            break;
        }
    }
    for (; i < n; i++) {
        if (!big[i] && !small[i]) {
            printf(" %d", arr[i]);
        }
    }
    printf("\n");//格式错了一个数据点,如果数量是0,应该输出一个空行
    return 0;
}

1046 划拳

#include 
#include 
#include 
using namespace std;

int A, B;

int main() {
    int n;
    cin >> n;
    int c1, c2, c3, c4;
    while (n--) {
        cin >> c1 >> c2 >> c3 >> c4;
        int ans = c1 + c3;
        if (c2 != ans && c4 != ans || c2 == ans && c4 == ans) {
            continue;
        }
        else if (c2 == ans) B++;
        else A++;
    }
    printf("%d %d", A, B);
    return 0;
}

1047 编程团体赛

#include 
#include 
#include 
using namespace std;

int res[1005];

int main() {
    int n;
    cin >> n;
    int team, member, score;
    for (int i = 0; i < n; i++) {
        scanf("%d-%d%d", &team, &member, &score);
        res[team] += score;
    }
    int index = 0;
    for (int i = 1; i < 1001; i++) {
        if (res[i] > res[index])index = i;
    }
    printf("%d %d", index, res[index]);
    return 0;
}

1048 数字加密

之前的一些题目数据特殊,可以说只是坑了一点。

这题目完全就是不严谨, 卡了两个数据过不了,百度查了下才发现,如果B没有A的位数长,需要在B前面填充'0'成为与A一样长的字符串。 题目里面没有说,测试数据中也没有体现。

#include 
#include 
#include 
#include 
#include 
using namespace std;

int main() {
    string s1, s2;
    cin >> s1 >> s2;
    vectora, b;
    a.push_back(0); b.push_back(0);
    for (int i = s1.length() - 1; i >= 0; i--)a.push_back(s1[i] ^ 48);
    for (int i = s2.length() - 1; i >= 0; i--)b.push_back(s2[i] ^ 48);
    while (b.size() < a.size())b.push_back(0);
    for (int i = 1; i < a.size() ; i++) {
        if (i & 1) {
            b[i] += a[i];
            b[i] %= 13;
        }
        else {
            b[i] -= a[i];
            if (b[i] < 0)b[i] += 10;
        }
    }
    for (int i = b.size() - 1; i >= 1; i--) {
        if (b[i] >= 10) {
            if (b[i] == 10)
                printf("J");
            else if (b[i] == 11)
                printf("Q");
            else
                printf("K");
        }
        else {
            printf("%d", b[i]);
        }
    }
    return 0;
}

1049 数列的片段和

找出规律,然后就是尽量减少计算,保证精度。

#include 
#include 
#include 
#include 
#include 
using namespace std;

double arr[100005];
//int cnt[1000];
int main() {
    int n;
    cin >> n;
    double t, res = 0;
    for (int i = 0; i < n; i++)
    {
        scanf("%lf", &t);
        res += t * (i + 1) * (n - i);
    }
    printf("%.2lf", res);
    /*
    计算太多,精度不够,换种成上面等价的方式
    double res = 0;
    int temp = n, increase = n - 2;
    for (int i = 0; i < n / 2; i++) {
        res += (temp * arr[i] + temp * arr[n - i - 1]);
        temp += increase;
        increase -= 2;
    }
    if (n & 1) {
        res += (temp + 1) * arr[n / 2 + 1];
    }
    printf("%.2lf", res);*/

    //打表找规律
    //for (int i = 0; i < n; i++) {
    //  for (int j = i; j < n; j++) {
    //      //printf("%d ", arr[i]);
    //      for (int k = i; k <= j; k++) {
    //          printf("%d ", arr[k]);
    //          cnt[k]++;
    //      }
    //      cout << endl;
    //  }
    //}

    //for (int i = 0; i < n; i++) {
    //  printf("%d ", cnt[i]);
    //}
    return 0;
}

1050 螺旋矩阵

第一个注意点是maze没法直接开,因为如果N可能是一个特别大的素数。

用深搜的思想来填表会容易很多。

#include 
#include 
#include 
#include 
#include 
using namespace std;

int N, m, n;
int arr[100005];
int **maze;
int dir[4][2] = { {0,1}, {1,0},{0,-1},{-1,0} };

//i,j位置,k方向
void fillForm(int x, int y, int k, int i) {
    if (i == N)
        return;
    int tox = x + dir[k][0], toy = y + dir[k][1];
    if (maze[tox][toy] == 0) {
        maze[tox][toy] = arr[i];
        fillForm(tox, toy, k, i + 1);
    }
    else {
        fillForm(x, y, (k + 1) % 4, i);
    }
}

bool cmp(int a, int b) { return a > b; }
int main() {
    cin >> N;
    for (int i = 1; i <= N / i; i++) {
        if (N % i == 0) {
            n = i;
            m = N / n;
        }
    }
    maze = new int* [m + 2];

    for (int i = 0; i <= m + 1; i++) {
        maze[i] = new int[n + 2];
        fill(maze[i], maze[i] + n + 2, 0);
    }
    for (int i = 0; i < N; i++) {
        scanf("%d", &arr[i]);
    }
    sort(arr, arr + N, cmp);
    //标记边界
    for (int i = 0; i <= n + 1; i++) {
        maze[0][i] = -1;
        maze[m + 1][i] = -1;
    }
    for (int i = 0; i <= m + 1; i++) {
        maze[i][0] = -1;
        maze[i][n + 1] = -1;
    }
    maze[1][1] = arr[0];
    fillForm(1, 1, 0, 1);
    for (int i = 1; i <= m; i++) {
        printf("%d", maze[i][1]);
        for (int j = 2; j <= n; j++) {
            printf(" %d", maze[i][j]);
        }
        printf("\n");
    }
    return 0;
}

1051 复数乘法

就注意,直接 printf("%.2f",-0.003); 输出的是-0.00,这个负号是不该有的。

#include 
#include 
#include 
#include 
#include 
#include 
using namespace std;

int main() {
    double r1, p1, r2, p2;
    scanf("%lf%lf%lf%lf", &r1, &p1, &r2, &p2);
    /*
    double a1, b1, a2, b2;
    a1 = r1 * cos(p1); b1 = r1 * sin(p1);
    a2 = r2 * cos(p2); b2 = r2 * sin(p2);
    double a3 = a1 * a2 - b1 * b2;
    double b3 = a1 * b2 + a2 * b1;
    */
    //两角和差公式
    double a3 = r1 * r2 * cos(p1 + p2);
    double b3 = r1 * r2 * sin(p1 + p2);
    double accuracy = 0.005;
    if (fabs(a3) < accuracy) a3 = 0;
    if (fabs(b3) < accuracy) b3 = 0;
    printf("%.2lf%+.2lfi", a3, b3);
    return 0;
}

1052 卖个萌

这题真的很无趣,测试数据是没法跑不出来的。。。。像这个'╮',还有这个 '╭',特殊符号,直接赋值给 string能够输出,但用getchar(),scanf(),cin, getline 都读不出来。

#include 
#include 
#include 
using namespace std;
int main() {
    vector > v;
    for (int i = 0; i < 3; i++) {
        string s;
        getline(cin, s);
        vector row;
        int j = 0, k = 0;
        while (j < s.length()) {
            if (s[j] == '[') {
                while (k++ < s.length()) {
                    if (s[k] == ']') {
                        row.push_back(s.substr(j + 1, k - j - 1));
                        break;
                    }
                }
            }
            j++;
        }
        v.push_back(row);
    }
    int n;
    cin >> n;
    for (int i = 0; i < n; i++) {
        int a, b, c, d, e;
        cin >> a >> b >> c >> d >> e;
        if (a > v[0].size() || b > v[1].size() || c > v[2].size() || d > v[1].size() || e > v[0].size() || a < 1 || b < 1 || c < 1 || d < 1 || e < 1) {
            cout << "Are you kidding me? @\\/@" << endl;
            continue;
        }
        cout << v[0][a - 1] << "(" << v[1][b - 1] << v[2][c - 1] << v[1][d - 1] << ")" << v[0][e - 1] << endl;
    }
    return 0;
}

1053 住房空置率

#include 
#include 
#include 
#include 
#include 
#include 
using namespace std;

int maybe_empty, true_empty;

int main() {
    int N, D;
    double e, temp;
    cin >> N >> e >> D;
    int k;
    for (int i = 0; i < N; i++) {
        int cnt = 0;
        cin >> k;
        for (int j = 0; j < k; j++) {
            scanf("%lf", &temp);
            if (e > temp) cnt++;
        }
        if (cnt > k / 2) {//超过一半29-->15,30-->16
            k > D ? true_empty++ : maybe_empty++;
        }
    }
    printf("%.1lf%c", (double)maybe_empty / N * 100, '%');
    printf(" %.1lf%c", (double)true_empty / N * 100, '%');
    return 0;
}

1054 求平均值

这一题纯粹搞人心态,非常坑人的输出格式,K为1的时候,输出的是number,不是numbers。
一直没发现,以为是少判断了什么情况,修改了好久。最后发现是number的问题,加上注释的全都是不涉及到的错误格式。写之前不知道下面这些函数,代码写的很冗余,不过在网上发现了一种非常便捷的解法。

C++将string转化为int或者double

转化为int,有两种方式:

string s = "123";

int c = atoi(s.c_str());

或者

int c = stoi(s);

将string转化为double,也是两种方式。

string s = "123.5";

double c = atof(s.c_str())

或者

double c = stod(s);

#include 
#include 
#include 
#include 
#include 
#include 
using namespace std;

double sum = 0;
int isLegal(string s) {
    //if (s[s.length() - 1] == '.')return -1;//小数点在最后一位
    bool flag = false;
    int digit = 0, i = 0;
    if (s[0] == '-') i = 1;
    //if (s[i] == '.')return -1;//小数点在最高位
    //if (s[i] == '0')i++, flag = true;//首位为0,整数部分不许再有0
    //整数部分

    while (i < s.length() && s[i] != '.') {
        if (!(s[i] >= '0' && s[i] <= '9') || (s[i] == '0' && flag))
            return -1;
        i++;
    }
    //if (s[0] == '-' && i == 1)return -1;//只有一个负号的情况
    i++;
    //小数部分
    while (i < s.length()) {
        if (!(s[i] >= '0' && s[i] <= '9'))
            return -1;
        else
            digit++;
        i++;
    }
    if (digit > 2)
        return -1;
    return digit;
}

double toDouble(string s, int digit) {
    int res = 0, i = 0, flag = 1;
    if (s[0] == '-')i = 1, flag = -1;
    for (; i < s.length(); i++) {
        if (s[i] != '.') {
            res = (res << 3) + (res << 1) + (s[i] ^ 48);
            //避免字符串过长,爆int,当前数一定是大于1000或小于-1000的,直接返回一个非法值
            if (res > 1000 * pow(10, digit))return 1001.0;
        }
    }
    return flag * res / pow(10, digit);
}
int main() {
    int n, cnt = 0;
    string s;
    cin >> n;
    for (int i = 0; i < n; i++) {
        cin >> s;
        int temp = isLegal(s);
        if (temp != -1) {
            double res = toDouble(s, temp);
            if (res >= -1000 && res <= 1000) {
                sum += res;
                cnt++;
            }
            else {
                printf("ERROR:");
                cout << ' ' << s << ' ';
                printf("is not a legal number\n");
            }
        }
        else {
            printf("ERROR:");
            cout << ' ' << s << ' ';
            printf("is not a legal number\n");
        }
    }
    if (cnt == 0) {
        printf("The average of 0 numbers is Undefined");
    }
    else {
        if (cnt == 1)
            printf("The average of %d number is %.2lf", cnt, sum / cnt);
        else
            printf("The average of %d numbers is %.2lf", cnt, sum / cnt);
    }
    return 0;
}

使用sscanf和sprintf函数
sscanf() – 从一个字符串中读进与指定格式相符的数据
sprintf() – 字符串格式化命令,主要功能是把格式化的数据写入某个字符串中

#include 
#include 
#include 
using namespace std;
int main() {
    int n, cnt = 0;
    char a[50], b[50];
    double temp, sum = 0.0;
    cin >> n;
    for(int i = 0; i < n; i++) {
        scanf("%s", a);
        sscanf(a, "%lf", &temp);
        sprintf(b, "%.2f",temp);
        int flag = 0;
        for(int j = 0; j < strlen(a); j++)
            if(a[j] != b[j]) flag = 1;
        if(flag || temp < -1000 || temp > 1000) {
            printf("ERROR: %s is not a legal number\n", a);
            continue;
        } else {
            sum += temp;
            cnt++;
        }
    }
    if(cnt == 1)
        printf("The average of 1 number is %.2f", sum);
    else if(cnt > 1)
        printf("The average of %d numbers is %.2f", cnt, sum / cnt);
    else
        printf("The average of 0 numbers is Undefined");
    return 0;
}

1055 集体照

#include 
#include 
using namespace std;

typedef pair P;

bool cmp(P p1, P p2) {
    if (p1.second == p2.second)
        return p1.first < p2.first;
    else
        return p1.second > p2.second;
}

P stu[10005];
string str[10005];
void print(int i, int cnt) {
    int pos = cnt / 2 + 1, offset = 1, flag = -1, destination;
    if (cnt & 1)destination = cnt;
    else destination = 1;
    while (pos != destination) {
        str[pos] = stu[i].first;
        pos += offset * flag;
        offset++;
        flag = ~flag + 1;
        i++;
    }
    str[pos] = stu[i].first;
    for (int i = 1; i <= cnt; i++) {
        cout << str[i];
        if (i != cnt)cout << ' ';
    }
    cout << endl;
}

int main() {
    int n, k;
    cin >> n >> k;
    for (int i = 0; i < n; i++) {
        cin >> stu[i].first >> stu[i].second;
    }
    sort(stu, stu + n, cmp);

    int common = n / k;
    int last = common + n % k;
    print(0, last);
    for (int i = last; i < n; i += common) {
        print(i, common);
    }
    return 0;
}

1056 组合数的和

#include 
#include 
#include 
using namespace std;

int arr[15];
int res;

int main() {

    int n;
    cin >> n;
    for (int i = 0; i < n; i++) {
        scanf("%d", &arr[i]);
    }

    for (int i = 0; i < n; i++) {
        for (int j = 0; j < n; j++) {
            if (i == j)continue;
            int temp = arr[i] * 10 + arr[j];
            res += temp;
        }
    }
    printf("%d", res);
    return 0;
}

1057 数零壹

#include 
#include 
#include 
using namespace std;

int main() {
    int sum = 0;
    char c;
    while ((c = getchar()) != '\n') {
        if (isalpha(c)) {
            c = tolower(c);
            sum += c - 'a' + 1;
        }
    }
    int zero = 0, one = 0;

    while (sum) {
        (sum & 1) ? one++ : zero++;
        sum >>= 1;
    }
    printf("%d %d", zero, one);
    return 0;
}

1058 选择题

#include 
#include 
#include 
#include 
using namespace std;

struct problem {
    int fullScore, optionCount, rightCount;
    bool rightOption[26] = { false };
}P[105];
int wrong[105];
int main() {
    char c;
    int N, M;
    cin >> N >> M;
    for (int i = 0; i < M; i++) {
        scanf("%d%d%d", &P[i].fullScore, &P[i].optionCount, &P[i].rightCount);
        getchar();
        for (int j = 0; j < P[i].rightCount; j++) {
            c = getchar();
            P[i].rightOption[c - 'a'] = true;
            getchar();
        }
    }

    for (int i = 0; i < N; i++) {
        int score = 0, answer_cnt;
        for (int j = 0; j < M; j++) {
            getchar();//'('
            scanf("%d", &answer_cnt);
            int temp = 0;//记录答案个数
            for (int k = 0; k < answer_cnt; k++) {
                getchar();//' '
                c = getchar();
                if (P[j].rightOption[c - 'a']) {
                    temp++;
                }
                //出现了错误的答案,但是不能break,后面还要读取,就给temp一个必然错误的值
                else {
                    temp = 26;
                }
            }
            if (temp == P[j].rightCount)
                score += P[j].fullScore;
            else wrong[j]++;
            getchar();//')'
            getchar();//' ','\n'
        }
        printf("%d\n", score);
    }
    int mmax = 0;
    for (int i = 0; i < M; i++) {
        if (wrong[i] > mmax)mmax = wrong[i];
    }
    if (mmax == 0) {
        printf("Too simple");
        return 0;
    }
    printf("%d", mmax);
    for (int i = 0; i < M; i++) {
        if (wrong[i] == mmax) {
            printf(" %d", i + 1);
        }
    }
    return 0;
}

1059 C语言竞赛

#include 
#include 
#include 
#include 
#include 
using namespace std;

#define N 10005
int P[N],total;

int flag[N], Rank[N];

void Aisieve() {
    for (int i = 2; i < N; i++) {
        if (!P[i]) {
            for (int j = i * 2; j < N; j += i) {
                P[j] = true;
            }
        }
    }
}

int main() {
    Aisieve();
    int n, champion = 0, a;
    cin >> n;
    scanf("%d", &champion);
    flag[champion] = 1;
    for (int i = 1; i < n; i++) {
        scanf("%d", &a);
        Rank[a] = i + 1;
        flag[a] = 1;
    }

    int k;
    cin >> k;
    for (int i = 0; i < k; i++) {
        scanf("%d", &a);
        printf("%04d: ", a);
        if (flag[a] == 1) {
            if (a == champion)cout << "Mystery Award" << endl;
            else if (!P[Rank[a]])cout << "Minion" << endl;
            else cout << "Chocolate" << endl;
            flag[a] = -1;
        }
        else if (flag[a] == -1) {
            cout << "Checked" << endl;
        }
        else {
            cout << "Are you kidding?" << endl;
        }
    }
    return 0;
}

1060 爱丁顿数

#include 
#include 
#include 
#include 
#include 
#include 
using namespace std;

#define N 100005
//int cnt[N];//记录每个距离骑行了多少天
unordered_mapcnt;

int main() {
    int n, a, mmax = 0;//最长距离
    cin >> n;
    for (int i = 0; i < n; i++) {
        scanf("%d", &a);
        cnt[a]++;
        mmax = a > mmax ? a : mmax;
    }

    int temp = 0;
    //从最长英里往下依次累加骑行天数,当累加天数大于等于当前英里数,i就是答案
    for (int i = mmax; i >= 0; i--) {
        if (temp >= i) {
            printf("%d", i);
            return 0;
        }
        temp += cnt[i];
    }
    printf("%d", 0);
    return 0;
}

1061 判断题

#include 
#include 
#include 
using namespace std;

int score[105];
int answer[105];
int res[105];

int main() {
    int n, m;
    cin >> n >> m;
    for (int i = 0; i < m; i++) {
        scanf("%d", &score[i]);
    }
    
    for (int i = 0; i < m; i++) {
        scanf("%d", &answer[i]);
    }
    int temp;
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < m; j++) {
            scanf("%d", &temp);
            res[i] += (temp == answer[j]) ? score[j] : 0;
        }
    }
    for (int i = 0; i < n; i++) {
        printf("%d\n", res[i]);
    }
    return 0;
}

1062 最简分数

#include 
using namespace std;

int gcd(int a,int b) {
    return b == 0 ? a : gcd(b, a % b);
}

int lcm(int a, int b) {
    return a / gcd(a, b) * b;
}
int lcm(int a, int b, int c) {
    int l1 = lcm(a, b);
    return lcm(l1, c);
}

int main() {
    int n1, m1, n2, m2, k;
    scanf("%d/%d %d/%d %d", &n1, &m1, &n2, &m2, &k);
    int M = lcm(m1, m2, k);
    n1 = n1 * M / m1;
    n2 = n2 * M / m2;
    if (n1 > n2)
        swap(n1, n2);
    int i = n1 + 1;
    int standard = M / k;
    for (; i < n2; i++) {
        if (gcd(i, M) == standard) {
            printf("%d/%d", i/standard, k);
            i++;
            break;
        }
    }
    for (; i < n2; i++) {
        if (gcd(i, M) == standard) {
            printf(" %d/%d", i / standard, k);
        }
    }
    return 0;
}

1063 计算谱半径

#include 
#include 
#include 
#include 
using namespace std;

double res;
int main() {
    int n;
    cin >> n;
    int a, b;
    for (int i = 0; i < n; i++) {
        scanf("%d%d", &a, &b);
        double temp = sqrt(a * a + b * b);
        if (temp > res)res = temp;
    }
    
    printf("%.2lf", res);
    return 0;
}

1064 朋友数

#include 
#include 
#include 
#include 
#include 
using namespace std;

bool ans[40];
int cnt;

int main() {
    int n, k;
    cin >> n;
    
    for (int i = 0; i < n; i++) {
        scanf("%d", &k);
        int temp = 0;
        while (k) {
            temp += k % 10;
            k /= 10;
        }
        if (!ans[temp]) {
            cnt++;
            ans[temp] = true;
        }
    }
    printf("%d\n", cnt);
    
    for (int i = 0, k = 0; i <= 36; i++) {
        if (ans[i]) {
            printf("%d", i);
            k++;
            if (k != cnt) {
                printf(" ");
            }
        }
    }
    return 0;
}

1065 单身狗

#include 
#include 
#include 
#include 
#include 
using namespace std;

bool check[100005] = { false };

int main(){
    vector list;
    vector res;
    map ma;
    int n,m,x,y;
    scanf("%d", &n);
    for (int i = 0; i < n; i++){
        scanf("%d%d", &x,&y);
        ma[x] = y;
        ma[y] = x;
    }
    scanf("%d", &m);
    for (int i = 0; i < m; i++){
        scanf("%d", &x);
        check[x] = true;
        list.push_back(x);
    }
    for (int i = 0; i < list.size(); i++){
        if (ma.find(list[i]) == ma.end()||!check[ma[list[i]]])
            res.push_back(list[i]);
    }
    sort(res.begin(), res.end());
    printf("%d\n", res.size());

    if (!res.empty())
        printf("%05d", res[0]);
    for (int i = 1; i < res.size(); i++){
        printf(" %05d", res[i]);
    }
    return 0;
}

1066 图像过滤

#include 
#include 
#include 
#include 
#include 
using namespace std;

int M, N, low, high, substitute;
int main() {
    int c;
    scanf("%d%d%d%d%d", &M, &N, &low, &high, &substitute);
    for (int i = 0; i < M; i++) {
        for (int j = 0; j < N; j++) {
            scanf("%d", &c);
            if (c >= low && c <= high) 
                printf("%03d", substitute);
            else
                printf("%03d", c);
            if (j != N - 1)putchar(' ');
            else putchar('\n');
        }
    }
    return 0;
}

1067 试密码

这题通过率这么低不是没有道理的,永远用最大的恶意取揣测出题人。

1470173-20191121120044931-899144802.png

但是没有说用户尝试的密码不含空格、Tab等字符。。。本来就想着要用 getline,看到红框里的这句觉得不需,还是出题人技高一筹啊。

其它的注意点:

  1. 如果输入是 "#" 不作输出,结束程序。
  2. 如果输入是正确答案,输出"Welcome in",结束程序。
  3. 如果密码错误则输出"Wrong password: xxx",如果达到了允许尝试的次数,则不接受下一个输入,直接输出"Account locked",结束允许。
#include 
#include 
#include 
#include 
#include 
using namespace std;

string passworrd;
int main() {
    string str;
    int n;
    cin >> passworrd >> n;
    cin.ignore();
    for (int i = 0; i < n; i++) {
        //cin >> str;
        getline(cin, str);
        if (str.compare("#") == 0) {
            return 0;
        }
        if (str.compare(passworrd) == 0) {
            cout << "Welcome in" << endl;
            return 0;
        }
        else {
            cout << "Wrong password: " << str << endl;  
        }
    }
    cout << "Account locked" << endl;
    return 0;
}

1068 万绿丛中一点红

就注意一点,题目把行、列故意“倒”了过来,最后的输出也是。

#include 
#include 
#include 
#include 
#include 
#include 
using namespace std;

int m, n, tol;
int M[1005][1005];
unordered_mapmap;

int dir[8][2] = { {-1,0},{1,0},{1,-1} ,{1,1},{0,1},{0,-1},{-1,1} ,{-1,-1} };

bool judge(int x, int y) {
    for (int i = 0; i < 8; i++) {
        int tox = x + dir[i][0], toy = y + dir[i][1];
        if (tox >= 1 && tox <= n && toy >= 1 && toy <= m) {
            if (abs(M[tox][toy] - M[x][y]) <= tol)
                return false;
        }
    }
    return true;
}

int main() {
    cin >> m >> n >> tol;
    for (int i = 1; i <= n; i++) {
        for (int j = 1; j <= m; j++) {
            scanf("%d", &M[i][j]);
            map[M[i][j]]++;
        }
    }
    int cnt = 0, x, y;
    for (int i = 1; i <= n; i++) {
        for (int j = 1; j <= m; j++) {
            if (map[M[i][j]] == 1 && judge(i, j)) {
                cnt++;
                x = i; y = j;
            }
        }
    }
    if (cnt == 0) {
        printf("Not Exist");
    }
    else if (cnt == 1) {
        printf("(%d, %d): %d", y, x, M[x][y]);
    }
    else {
        printf("Not Unique");
    }
    return 0;
}

1069 微博转发抽奖

#include 
#include 
#include 
#include 
using namespace std;

unordered_mapmapp;

int main() {
    int m, n, s;
    cin >> m >> n >> s;
    if (s > m) {
        cout << "Keep going...";
        return 0;
    }
    int temp = 0;
    string str;
    for (int i = 1; i <= m; i++) {
        cin >> str;
        if (i >= s) {
            temp--;
            if (temp <= 0 && !mapp[str]) {
                cout << str << endl;
                mapp[str] = true;
                temp = n;
            }
        }
    }
    return 0;
}

1070 结绳

哈夫曼的思想,从所有绳子中选最短的两根绳子,连起来再放回去,直到只剩下最后一根绳子。

当两根绳子长度和第一次为奇数时,会出现 \(0.5\) 的小数,如果下一次长度和为奇数则小数部分为\((1+0.5) / 2= 0.75\),如果长度和为偶数则为\(0.25\)。所以无论出现什么情况,小数部分一定大于等于0,小于1。碰到长度和为奇数直接下取整就行了。

#include 
#include 
#include 
#include 
#include 
using namespace std;

struct cmp {
    bool operator()(int a,int b) {
        return a > b;
    }
};
priority_queue, cmp> q;

int main() {
    int n, c;
    cin >> n;
    for (int i = 0; i < n; i++) {
        scanf("%d", &c);
        q.push(c);
    }
    while (q.size() > 1) {
        int i = q.top(); q.pop();
        int j = q.top(); q.pop();
        int temp = i + j;
        q.push(temp / 2);
    }
    //flag = (flag == 0) ? 1 : flag;
    printf("%d", q.top());
    return 0;
}

1071 小赌怡情

#include 
#include 
#include 
#include 
#include 
using namespace std;

int main() {
    int total, k;
    cin >> total >> k;
    int n1, b, t, n2;
    for (int i = 0; i < k; i++) {
        //0小,1大
        scanf("%d%d%d%d", &n1, &b, &t, &n2);
        if (t > total) {
            printf("Not enough tokens.  Total = %d.\n", total);
            continue;
        }
        if ((n1 < n2 && b == 1) || (n1 > n2 && b == 0)) {
            total += t;
            printf("Win %d!  Total = %d.\n", t, total);
        }
        else {
            total -= t;
            //total不可能出现负的情况,但这里数据没有下坑。。。
            //if (total < 0)total = 0;
            printf("Lose %d.  Total = %d.\n", t, total);
            if (total == 0) {
                printf("Game Over.");
                return 0;
            }
        }
    }
    return 0;
}

1072 开学寄语

#include 
#include 
#include 
#include 
#include 
using namespace std;

bool flag[10000];

int main() {
    string name;
    int n, m, c, k, s_num = 0, t_num = 0;
    cin >> n >> m;
    for (int i = 0; i < m; i++) {
        scanf("%d", &c);
        flag[c] = true;
    }
    for (int i = 0; i < n; i++) {
        cin >> name >> k;
        bool is_first = true;
        for (int j = 0; j < k; j++) {
            scanf("%d", &c);
            if (flag[c]) {
                if (is_first) {
                    cout << name << ":";
                    is_first = false;
                }
                printf(" %04d", c);
                t_num++;
            }
        }
        if (!is_first) {
            s_num++;
            printf("\n");
        }
    }
    printf("%d %d", s_num, t_num);
    return 0;
}

1073 多选题常见计分法

最讨厌这种内容巨多的题目。

看了 大佬的题解 用整数来模拟记录答案和回答。

可以选择用 bool rightOption[105][5] 来记录正确答案,但都是要写很长很长。

#include 
#include 
#include 
#include 
using namespace std;

int fullScore[105], optionCount[105], rightCount[105], rightOption[105], wrong[105];
int standard[5] = { 1,2,4,8,16 };

int wrongOption[105][5];

int main() {
    char c;
    int N, M;
    cin >> N >> M;
    for (int i = 0; i < M; i++) {
        scanf("%d%d%d", &fullScore[i], &optionCount[i], &rightCount[i]);
        for (int j = 0; j < rightCount[i]; j++) {
            scanf(" %c", &c);
            rightOption[i] += standard[c - 'a'];
        }
    }

    for (int i = 0; i < N; i++) {
        double grade = 0;
        for (int j = 0; j < M; j++) {
            getchar();
            int temp, respond = 0;
            scanf("(%d", &temp);
            for (int k = 0; k < temp; k++) {
                scanf(" %c", &c);
                respond += standard[c - 'a'];   
            }
            getchar();
            int c1 = respond ^ rightOption[j];
            if (c1 == 0) {
                grade += fullScore[j];
            }
            else {
                if ((respond | rightOption[j]) == rightOption[j]) {
                    grade += fullScore[j] / 2.0;
                }
                for (int k = 0; k < 5; k++) {
                    if (c1 & standard[k])
                        wrongOption[j][k]++;
                }
            }
        }
        printf("%.1lf\n", grade);
    }
    int mmax = 0;
    for (int i = 0; i < M; i++) {
        for (int j = 0; j < 5; j++) {
            mmax = wrongOption[i][j] > mmax ? wrongOption[i][j] : mmax;
        }
    }

    if (mmax == 0) {
        cout << "Too simple";
        return 0;
    }
    for (int i = 0; i < M; i++) {
        for (int j = 0; j < 5; j++) {
            if (wrongOption[i][j] == mmax) {
                printf("%d %d-%c\n", mmax, i + 1, ('a' + j));
            }
        }
    }
    return 0;
}

1074 宇宙无敌加法器

N到了20位,不能用long long。如果N都是2222这样的,两个数相加出来的和是很有可能超过N位的,对于本题,超过N位则没有意义了,所以测试数据里一定不会出现这种情况。

#include 
#include 
#include 
#include 
#include  
using namespace std;

int main() {
    vector a, b, N;
    string s1, s2, s3;
    cin >> s1 >> s2 >> s3;
    for (int i = s1.length() - 1; i >= 0; i--) N.push_back(s1[i] ^ 48);
    for (int i = s2.length() - 1; i >= 0; i--) a.push_back(s2[i] ^ 48);
    for (int i = s3.length() - 1; i >= 0; i--) b.push_back(s3[i] ^ 48);
    if (a.size() < b.size())a.swap(b);
    for (int i = 0; i < b.size(); i++) 
        a[i] += b[i];
    for (int i = 0; i < a.size(); i++) {
        int k = (N[i] == 0) ? 10 : N[i];
        if (a[i] >= k) {
            if (i != a.size() - 1)
                a[i + 1] += a[i] / k;
            else a.push_back(a[i] / k);
            a[i] %= k;
        }
    }
    while (a[a.size() - 1] == 0 && a.size() > 1)a.pop_back();
    for (int i = a.size() - 1; i >= 0; i--) {
        printf("%d", a[i]);
    }
    return 0;
}

1075 链表元素分类

负元素摆在最前面,然后小于等于K的元素应该摆在大于K的元素前面。用三个vector,分别存负、小于等于k、大于k的结点,然后依次输出。

最后输出,由于数据可能性很多,不是每种元素都一定有,最简单的输出办法是把三个vector合并成一个,然后输出。这份代码的输出借鉴了大佬的思想。

#include 
#include 
#include 
#include 
using namespace std;

int Data[100005], Next[100005];
vectorList[3];
int main() {
    int first, n, k;
    cin >> first >> n >> k;
    int t;
    for (int i = 0; i < n; i++) {
        cin >> t;
        cin >> Data[t] >> Next[t];
    }
    while (first != -1) {
        if (Data[first] < 0) {
            List[0].push_back(first);
        }
        else if (Data[first] <= k) {
            List[1].push_back(first);
        }
        else {
            List[2].push_back(first);
        }
        first = Next[first];
    }
    
    
    int flag = 0;
    for (int i = 0; i < 3; i++) {
        for (int j = 0; j < List[i].size(); j++) {
            if (flag == 0) {
                printf("%05d %d ", List[i][j], Data[List[i][j]]);
                flag = 1;
            }
            else {
                printf("%05d\n%05d %d ", List[i][j], List[i][j], Data[List[i][j]]);
            }
        }
    }
    printf("-1");
    return 0;
}

1076 Wifi密码

#include 
#include 
#include 
#include 
#include 
using namespace std;

vectorres;
int main() {
    int n;
    cin >> n;
    string s;
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < 4; j++) {
            cin >> s;
            if (s[2] == 'T') {
                res.push_back(s[0] - 'A' + 1);
            }
        }
    }
    for (int i = 0; i < n; i++) {
        printf("%d", res[i]);
 }
    return 0;
}

1077 互评成绩计算

#include 
#include 
#include 
#include 
#include  
using namespace std;


vector arr;
int main(){
    int N, fullScore;
    cin >> N >> fullScore;
    for (int i = 0; i < N; i++) {
        int G1 = 0, G2, temp;
        arr.clear();
        cin >> G2;
        for (int j = 1; j < N; j++) {
            cin >> temp;
            if (temp >= 0 && temp <= fullScore)
                arr.push_back(temp);
        }
        sort(arr.begin(), arr.end());
        for (int i = 1; i < arr.size() - 1; i++) {
            G1 += arr[i];
        }
        int score = round((G2 + G1 * 1.0 / (arr.size() - 2)) / 2);
        printf("%d\n", score);
    }
    return 0;
}

1078 字符串压缩与解压

#include 
#include 
#include  
using namespace std;

char str[1005];
int cnt[1005];

int main() {
    int i = 0;
    char type = getchar();
    //scanf("%c\n", &type);虽然有点迷这样写为什么会段错误,但是以后别这样写就是了
    getchar();
    while ((str[i++] = getchar()) != '\n');
    str[i - 1] == 0;
    int len = strlen(str);
    if (type == 'C') {
        cnt[0] = 1;
        for (int i = 1; i < len; i++) {
            if (str[i - 1] == str[i]) {
                cnt[i] = cnt[i - 1] + 1;
            }
            else cnt[i] = 1;
        }

        for (int i = 0; i < len; i++) {
            if (i == len - 1 || cnt[i + 1] == 1) {
                if (cnt[i] == 1)putchar(str[i]);
                else printf("%d%c", cnt[i], str[i]);
            }
        }
    }
    else {
        for (int i = 0; i < len; i++) {
            int k = 0;
            while (str[i] >= '0' && str[i] <= '9') {
                k = (k << 3) + (k << 1) + (str[i] ^ 48);
                i++;
            }
            k = (k == 0) ? 1 : k;
            for (int j = 0; j < k; j++) {
                putchar(str[i]);
            }
        }
    }
    return 0;
}

1079 延迟的回文数

#include 
#include 
#include 
#include  
using namespace std;

bool Ispalindromic(vector& s) {
    int i = 0, j = s.size() - 1;
    while (i < j) {
        if (s[i] != s[j])return false;
        i++; j--;
    }
    return true;
}

void Carry(vector& a) {
    for (int i = 0; i < a.size(); i++) {
        if (a[i] >= 10) {
            if (i != a.size() - 1)
                a[i + 1] += 1;
            else a.push_back(1);
            a[i] -= 10;
        }
    }
}

void Add(vector& a, vector& b) {
    for (int i = 0; i < a.size(); i++) {
        a[i] += b[i];
    }
    Carry(a);
}

void reversePrintVector(vector& a) {
    for (int i = a.size() - 1; i >= 0; i--) {
        printf("%d", a[i]);
    }
    
}

int main() {
    string s;
    cin >> s;
    vectora, b;
    for (int i = 0; i < s.length(); i++) {
        a.push_back(s[s.length() - 1 - i] ^ 48);
        b.push_back(s[i] ^ 48);
    }
    int step = 0;
    while (!Ispalindromic(a) && step < 10) {
        reversePrintVector(a); printf(" + ");reversePrintVector(b);
        Add(a, b);
        printf(" = ");reversePrintVector(a);printf("\n");
        b = a;
        reverse(b.begin(), b.end());
        step++;
    }
    if (step < 10) {
        reversePrintVector(a);
        printf(" is a palindromic number.");
    }
    else {
        printf("Not found in 10 iterations.");
    }
    
    return 0;
}

1080 MOOC期终成绩

注意一点,用 map 来字符串对应记录索引的话,千万别从0开始记,血泪史。。。

#include 
#include 
#include 
#include 
#include 
#include 
using namespace std;

struct STU {
    string name;
    int Gp = -1, Gm = -1, Gf = -1, G;
    bool operator<(STU s) {
        if (G == s.G) {
            return name < s.name;
        }
        return G > s.G;
    }
}stu[300005];
unordered_mapmmap;
int main() {
    string s;
    int P, M, N, temp, num = 1;
    cin >> P >> M >> N;
    for (int i = 0; i < P; i++) {
        cin >> s >> temp;
        if (temp >= 200) {
            stu[num].name = s; stu[num].Gp = temp;
            mmap[s] = num++;
        }
    }
    for (int i = 0; i < M; i++) {
        cin >> s >> temp;
        if (mmap[s] != 0) {
            stu[mmap[s]].Gm = temp;
        }
    }
    for (int i = 0; i < N; i++) {
        cin >> s >> temp;
        if (mmap[s] != 0) {
            stu[mmap[s]].Gf = temp;
        }
    }

    for (int i = 1; i < num ; i++) {
        if (stu[i].Gm > stu[i].Gf) {
            stu[i].G = (round)(stu[i].Gm * 0.4 + stu[i].Gf * 0.6);
        }
        else stu[i].G = stu[i].Gf;
    }
    sort(stu+1, stu + num );
    for (int i = 1; i < num  && stu[i].G >= 60; i++) {
        cout << stu[i].name << ' ' << stu[i].Gp << ' ' << stu[i].Gm << ' ' << stu[i].Gf << ' ' << stu[i].G << endl;
    }
    return 0;
}

1081 检查密码

稍微有点小迷,没说全部为'.'的时候输出什么,不过测试数据里面也没有。

#include 
#include 
#include 
#include 
#include 
#include  
using namespace std;

bool digital, alpha;
bool judge(string s) {
    for (int i = 0; i < s.length(); i++) {
        if (isalpha(s[i]))alpha = true;
        else if (isdigit(s[i]))digital = true;
        else {
            if (s[i] != '.')return false;
        }
    }
    return true;
}

int main(){
    string s;
    int N;
    cin >> N;
    cin.ignore();
    for (int i = 0; i < N; i++) {
        digital = false; alpha = false;
        getline(cin, s);
        if (s.length() < 6) {
            cout << "Your password is tai duan le." << endl;
        }
        else if (judge(s)) {
            if (digital && !alpha) {
                cout << "Your password needs zi mu." << endl;
            }
            else if (!digital && alpha) {
                cout << "Your password needs shu zi." << endl;
            }
            else if (digital && alpha) {
                cout << "Your password is wan mei." << endl;    
            }
            
        }
        else {
            cout << "Your password is tai luan le." << endl;
        }
    }
    return 0;
}

1082 射击比赛

#include 
#include 
#include 
#include  
using namespace std;

int champion = 1 << 30, rubbsh = 0, champion_index, rubbsh_index;


int main() {
    int n, x, y, c1;
    cin >> n;
    for (int i = 0; i < n; i++) {
        scanf("%d%d%d", &c1, &x, &y);
        int temp = x * x + y * y;
        if (temp > rubbsh) {
            rubbsh = temp;
            rubbsh_index = c1;
        }
        if (temp < champion) {
            champion = temp;
            champion_index = c1;
        }
    }
    printf("%04d %04d", champion_index, rubbsh_index);
    return 0;
}

1083 是否存在相等的差

#include 
#include 
#include 
#include  
using namespace std;

int arr[10005];
int res[10005];

int main() {
    int n;
    cin >> n;
    for (int i = 1; i <= n; i++) {
        scanf("%d", &arr[i]);
        res[abs(arr[i] - i)]++;
    }
    for (int i = n; i >= 0; i--) {
        if (res[i] > 1) {
            printf("%d %d\n", i, res[i]);
        }
    }
    return 0;
}

1084 外观数列

#include 
#include 
#include 
#include  
using namespace std;

string getRes(string s) {
    int cnt = 1;
    string res;
    char pre = s[0];
    for (int i = 1; i < s.length(); i++) {
        while (i < s.length() && s[i] == pre) {
            cnt++;
            i++;
        }
        res.append(1, pre);
        res.append(1, cnt + '0');
        if (i < s.length()) {
            pre = s[i];
            cnt = 1;
        }
    }
    if (cnt == 1) {
        res.append(1, pre);
        res.append(1, cnt + '0');
    }
    return res;
}

int main() {
    int d, n;
    cin >> d >> n;
    string s;
    while (d) {
        s.append(1, (d % 10) + '0');
        d /= 10;
    }

    for (int i = 0; i < n - 1; i++) {
        s = getRes(s);
        //cout << s << endl; 
    }
    cout << s << endl;
    return 0;
}

1085 PAT单位排行

用A,B,T来代表甲乙顶级的总分,根据题目的计算公式加权总分为
\[ B/1.5+A+T*1.5 \]
避免中途误差,把公式乘上150,也就是
\[ B*100+A*150+T*225 \]
然后除以150,再进行排序,输出。

#include 
#include 
#include 
#include 
#include 
#include 
using namespace std;

struct Node {
    string name;
    int score = 0, cnt = 0;
    bool operator<(Node n) {
        if (score != n.score) return score > n.score;
        if (cnt != n.cnt) return cnt < n.cnt;
        return name < n.name;
    }
}node[100005];
unordered_mapmmap;

int main() {
    string id, name;
    int n, score, num = 1;
    cin >> n;
    for (int i = 0; i < n; i++) {
        cin >> id >> score >> name;
        for (int i = 0; i < name.length(); i++) {
            if (name[i] >= 'A' && name[i] <= 'Z')name[i] += 32;
        }
        if (mmap[name] == 0) {
            node[num].name = name;
            mmap[name] = num++;
        }
        int k = mmap[name], flag = 100;
        if (id[0] == 'A')flag = 150;
        if (id[0] == 'T')flag = 225;
        node[k].cnt++;
        node[k].score += score * flag;
    }
    for (int i = 1; i < num; i++) {
        node[i].score /= 150;
    }
    sort(node + 1, node + num);
    int Rank = 1, temp = 1;
    printf("%d\n", num - 1);
    for (int i = 1; i < num; i++) {
        if (i > 1 && node[i].score < (node[i - 1].score)) {
            Rank = temp;
        }
        printf("%d %s %d %d\n", Rank, (node[i].name.c_str()), node[i].score , node[i].cnt);
            temp++;
    }
    return 0;
}

1086 就不告诉

很不严谨,没有说如果形如 50 这样的数,倒过来究竟是 05 还是 5。

第一遍这样写,错了,很明显不让输出前导0

#include 
#include  
using namespace std;

int main(){
    int m, n;
    cin >> m >> n;
    m *= n;
    do {
        printf("%d", m % 10);
        m /= 10;
    } while (m);
    return 0;
}

换一种写法

#include 
#include  
using namespace std;

int main(){
    int m, n;
    cin >> m >> n;
    m *= n;
    int res = 0;
    while (m) {
        res = res * 10 + m % 10;
        m /= 10;
    } 
    printf("%d", res);
    return 0;
}

1087 有多少不同的值

#include 
#include 
using namespace std;

int main() {
    int n;
    sets;
    scanf("%d", &n);
    for (int i = 1; i <= n; i++) {
        s.insert(i / 2 + i / 3 + i / 5);
    }
    printf("%d", s.size());
    return 0;
}

1088 三人行

枚举甲乙的值,计算是否存在丙的值,用 a,b,c 代指甲乙丙有:
\[ abs(a-b)=c\cdot x\\ b=c\cdot y\\ \]
联立两式得
\[ abs(a-b)\cdot y=b\cdot x \]
然后就是要注意一下丙可能为小数

#include 
#include 
#include 
#include  
using namespace std;

string str[3] = { "Gai","Ping","Cong" };
int cmp(int a, int b) {
    if (a > b)return 0;
    if (a == b)return 1;
    if (a < b)return 2;
}

//丙可能是小数,专门给丙的判断
int cmp(int a, int b, int flag) {
    //如果丙是小数
    if (flag && a == b) return 2;
    if (a > b)return 0;
    if (a == b)return 1;
    if (a < b)return 2;
}

int main() {
    bool flag = true;
    int M, x, y;
    cin >> M >> x >> y;
    //甲乙丙,a,b,c
    for (int a = 99; a >= 10; a--) {
        int b = ((a % 10) * 10 + a / 10);
        if (abs(a - b) * y == b * x) {
            printf("%d ", a);
            cout << str[cmp(M, a)] << ' ' << str[cmp(M, b)] << ' ' << str[cmp(M, b / y, b % y)] << endl;
            flag = false;
            break;
        }
    }
    if (flag) {
        cout << "No Solution" << endl;
    }
    return 0;
}

1089 狼人杀-简单版

贴大佬代码: https://blog.csdn.net/liuchuo/article/details/82560831 ,都是\(O(n^3)\) ,但是思路真好,代码真简洁,ORZ。

#include 
#include 
#include 
#include  
using namespace std;

int arr[105];
//假设ab是狼人,判断x否是说了实话
bool judge(int x, int a, int b) {
    //wolf is wolf
    if (arr[x] == -b || arr[x] == -a)return true;
    //human isn human
    if (arr[x] != a && arr[x] != b && arr[x] > 0)return true;
    return false;
}

int main() {
    int N, i, j, k;
    cin >> N;
    for (i = 1; i <= N; i++) {
        cin >> arr[i];
    }
    bool flag = false;
    for (i = 1; i <= N && !flag; i++) {
        for (j = i; j <= N && !flag; j++) {
            int cnt = 0;
            //假如 i 和 j是狼人
            if (i == j)continue;
            if (judge(i, i, j))cnt++;
            if (judge(j, i, j))cnt++;
            if (cnt != 1)
                continue;//只有一个狼人说了谎
            for (k = 1; k <= N; k++) {
                if (k != i && k != j) {
                    if (!judge(k, i, j)) {
                        cnt++;
                        //说谎人数超过了两个
                        if (cnt > 2)
                            break;
                    }   
                }
            }
            if (k == N + 1 && cnt == 2) {
                printf("%d %d\n", i, j);
                flag = true;
            }
        }
    }
    if (!flag) {
        cout << "No Solution" << endl;
    }
    return 0;
}

1090 危险品装箱

最开始用 mapbool>做超时了,然后换成 unordered_map (把两个五位数拼起来),还是会超时第三个点,稍微剪了一下枝过了。

#include 
#include 
#include 
#include 
#include 
#include 
#include 
using namespace std;

unordered_mapmmap;
int arr[1005];
bool flag[1000005];
int main() {
    int n, m;
    cin >> n >> m;

    int c1, c2;
    for (int i = 0; i < n; i++) {
        scanf("%d%d", &c1,&c2);
        flag[c1] = true; flag[c2] = true;
        mmap[c1 * 100000ll + c2] = true;
        mmap[c2 * 100000ll + c1] = true;
    }

    for (int i = 0; i < m; i++) {
        int k;
        scanf("%d", &k);
        for (int j = 0; j < k; j++) {
            scanf("%d", &arr[j]);
        }

        bool flag1 = true;
        for (int j1 = 0; j1 < k && flag1; j1++) {
            if (!flag[arr[j1]])continue;
            for (int j2 = j1 + 1; j2 < k && flag1; j2++) {
                if (mmap[arr[j1] * 100000ll + arr[j2]]) {
                    flag1 = false;
                    printf("No\n");
                }
            }
        }
        if (flag1)printf("Yes\n");
    }
    return 0;
}

虽然过了,但还是存在一些问题,如果K=1000,且这1000个物品全都是危险品,我这份代码铁定超时。看了大佬的思路 ,确实好很多。

#include 
#include 
#include 
using namespace std;
int main() {
    int n, k, t1, t2;
    map> m;
    scanf("%d%d", &n, &k);
    for (int i = 0; i < n; i++) {
        scanf("%d%d", &t1, &t2);
        m[t1].push_back(t2);
        m[t2].push_back(t1);
    }
    while (k--) {
        int cnt, flag = 0, a[100000] = {0};
        scanf("%d", &cnt);
        vector v(cnt);
        for (int i = 0; i < cnt; i++) {
            scanf("%d", &v[i]);
            a[v[i]] = 1;
        }
        for (int i = 0; i < v.size(); i++)
            for (int j = 0; j < m[v[i]].size(); j++)
                if (a[m[v[i]][j]] == 1) flag = 1;
        printf("%s\n",flag ? "No" :"Yes");
    }
    return 0;
}

1091 N-自守数

#include 
#include 
#include 
#include 
#include 
using namespace std;

int getBits(int a) {
    int res = 1;
    while (a) {
        res *= 10;
        a /= 10;
    }
    return res;
}
int main() {
    int m, k;
    cin >> m;
    for (int i = 0; i < m; i++) {
        cin >> k;
        int mod = getBits(k);
            int n = 1;
        for (; n < 10; n++) {
            if (n * k * k % mod == k) {
                printf("%d %d\n", n, n * k * k);
                break;
            }
        }
        if (n == 10) {
            printf("No\n");
        }
    }
    return 0;
}

1092 最好吃的月饼

#include 
#include 
#include 
#include  
using namespace std;

int arr[1005];
int mmax;

int main(){
    int m, n, temp;
    cin >> n >> m;
    for (int i = 0; i < m; i++) {
        for (int j = 1; j <= n; j++) {
            scanf("%d", &temp);
            arr[j] += temp;
        }
    }
    for (int i = 1; i <= n; i++) {
        if (arr[i] > mmax) {
            mmax = arr[i];
        }
    }
    printf("%d\n", mmax);
    int i;
    for (i = 1; i <= n; i++) {
        if (arr[i] == mmax) {
            printf("%d", i);
            i++;
            break;
        }
    }
    for (; i <= n; i++) {
        if (arr[i] == mmax) {
            printf(" %d", i);
        }
    }
}

1093 字符串A+B

#include 
#include 
using namespace std;

char res[256];
bool flag[256];
int main() {
    int i = 0;
    char c;
    while ((c = getchar()) != '\n') {
        if (!flag[c]) {
            res[i++] = c;
            flag[c] = true;
        }
    }

    while ((c = getchar()) != '\n') {
        if (!flag[c]) {
            res[i++] = c;
            flag[c] = true;
        }
    }

    for (int j = 0; j < i; j++) {
        putchar(res[j]);
    }

    return 0;
}

1094 谷歌的招聘

太惨了,没读懂题。。题意是要求输出前导0,我以为是不让输出。。。

看数据规模,K太大,不能打表,只能线性判断, \(O(L*log(k))\),怕超时,没敢用 substr + stoi ,结果实际数据规模很小,上当了。

#include 
#include 
#include 
#include 
#include 
#include 
using namespace std;

bool IsPrime(int x) {
    if (x < 2)return false;
    for (int i = 2; i * i <= x; i++) {
        if (x % i == 0)return false;
    }
    return true;
}

int getDigit(int x) {
    int res = 0;
    while (x) {
        res++;
        x /= 10;
    }
    return res==0 ? 1 : res;
}

int main() {
    int L, K;
    cin >> L >> K;
    string str;
    cin >> str;
    int temp = 0;
    for (int i = 0; i < K; i++) {
        temp = temp * 10 + str[i] - '0';
    }

    int standard = pow(10, K - 1);
    for (int i = 0; i + K <= str.length(); i++) {
        if (IsPrime(temp)) {
            int zeros = K - getDigit(temp);
            while (zeros) {
                putchar('0');
                zeros--;
            }
            printf("%d", temp);
            return 0;
        }
        if (i + K != str.length()) {
            temp %= standard;
            temp = temp * 10 + str[i + K] - '0';
        }
    }
    printf("%d", 404);
    return 0;
}

1095 解码PAT准考证

这种提问的题目,一般来说都是把答案全部存储起来,然后提问,直接输出答案。这一题我也是这样惯性思维了,但仔细算一下时间,完全不会超,第一版存答案的写了好久到最后每有头绪了。换成了问一次、算一次、输出一次。

#include 
#include 
#include 
#include 
using namespace std;
struct node {
    string id;
    int value;
}v[10005];
bool cmp(const node& a, const node& b) {
    return a.value != b.value ? a.value > b.value : a.id < b.id;
}
int main() {
    int n, k, num;
    string s;
    cin >> n >> k;
    for (int i = 0; i < n; i++)
        cin >> v[i].id >> v[i].value;
    for (int i = 1; i <= k; i++) {
        cin >> num >> s;
        printf("Case %d: %d %s\n", i, num, s.c_str());
        vector ans;
        int cnt = 0, sum = 0;
        if (num == 1) {
            for (int j = 0; j < n; j++)
                if (v[j].id[0] == s[0]) 
                    ans.push_back(v[j]);
        }
        else if (num == 2) {
            for (int j = 0; j < n; j++) {
                if (v[j].id.substr(1, 3) == s) {
                    cnt++;
                    sum += v[j].value;
                }
            }
            if (cnt != 0) 
                printf("%d %d\n", cnt, sum);
        }
        else if (num == 3) {
            unordered_map m;
            for (int j = 0; j < n; j++)
                if (v[j].id.substr(4, 6) == s) 
                    m[v[j].id.substr(1, 3)]++;
            for (unordered_map::iterator it = m.begin(); it != m.end(); it++) {
                ans.push_back({ it->first, it->second });
            }
        }
        sort(ans.begin(), ans.end(), cmp);
        for (int j = 0; j < ans.size(); j++) 
            printf("%s %d\n", ans[j].id.c_str(), ans[j].value);
        if (((num == 1 || num == 3) && ans.size() == 0) || (num == 2 && cnt == 0)) 
            printf("NA\n");
    }
    return 0;
}

你可能感兴趣的:(PAT (Basic Level) 乙组全题记录)