PTA 520钻石争霸赛 2021
阅读原文时间:2023年07月09日阅读:1

7-1 自动编程

签到题

#include

typedef long long ll;
const int maxm = 1e5 + 5;
const int infmax = INT_MAX;
const int infmin = INT_MIN;
using namespace std;

int main() {
int n;
cin >> n;
printf("print(%d)", n);
return 0;
}

7-2 加油冲鸭

签到

#include

typedef long long ll;
const int maxm = 1e5 + 5;
const int infmax = INT_MAX;
const int infmin = INT_MIN;
using namespace std;

int main() {
int n, m, s;
cin >> n >> m >> s;
int p = n - m * s;
if (p > n / 2) {
printf("hai sheng %d mi! jia you ya!\n", p);
} else {
printf("hai sheng %d mi! chong ya!\n", p);
}
return 0;
}

7-3 520的表白

签到

#include

typedef long long ll;
const int maxm = 1e5 + 5;
const int infmax = INT_MAX;
const int infmin = INT_MIN;
using namespace std;

int main() {
int n;
cin >> n;
for (int i = 0; i < 520; i++)
cout << n << "\n";
return 0;
}

7-4 奇葩楼层

遍历一遍楼层,带忌讳的数字不记数就行

#include

typedef long long ll;
const int maxm = 1e5 + 5;
const int infmax = INT_MAX;
const int infmin = INT_MIN;
using namespace std;

int main() {
int n, m;
cin >> n >> m;
int sum = 0;
for (int i = 1; i <= n; i++) {
int j = i, f = 1;
while (j) {
int k = j % 10;
j /= 10;
if (k == m) {
f = 0;
break;
}
}
if (f) sum++;
}
cout << sum << "\n";
return 0;
}

7-5 大勾股定理

平方和数太大,找规律,可以发现n = 1时,3开始;n = 2时,10开始, n = 3时,21开始。

1 * 3 = 3;

2 * 5 = 10;

3 * 7 = 21;

从而猜出n * (2 * n + 1)。

15分题不会搞很复杂的数列的。

#include

typedef long long ll;
const int maxm = 1e5 + 5;
const int infmax = INT_MAX;
const int infmin = INT_MIN;
using namespace std;

int main() {
int n;
cin >> n;
int k = n * (2 * n + 1);
for (int i = k; i <= k + n; i++) {
if (i == k) cout << i << "^2";
else cout << " + " << i << "^2";
}
cout << " =\n";
int j = k + n + 1, m = 0;
while (m < n) {
if (m == 0) cout << j << "^2";
else cout << " + " << j << "^2";
j++;
m++;
}
return 0;
}

7-6 矩阵列平移

模拟,注意写的时候不要把行和列写岔了就没啥问题

#include

typedef long long ll;
const int maxm = 1e5 + 5;
const int infmax = INT_MAX;
const int infmin = INT_MIN;
using namespace std;

int a[110][110];

int main() {
int n, k, x;
cin >> n >> k >> x;
for (int i = 1; i <= n; i++) for (int j = 1; j <= n; j++) cin >> a[i][j];
int m = 1;
for (int i = 2; i <= n; i += 2) { for (int j = n; j > m; j--)
a[j][i] = a[j - m][i];
for (int j = 1; j <= m; j++) a[j][i] = x; m++; if (m > k) m = 1;
}

for (int i = 1; i <= n; i++) {  
    int sum = 0, j = 1;  
    while (j <= n) sum += a\[i\]\[j\], j++;  
    if (i == 1)  
        cout << sum;  
    else cout << ' ' << sum;  
}  
return 0;  

}

7-7 约会大作战

题解在代码理,时间紧代码写的很不好,巨巨可以用结构体整理以下

#include

typedef long long ll;
const int maxm = 1e5 + 5;
const int infmax = INT_MAX;
const int infmin = INT_MIN;
using namespace std;

int a[110][110], b[110][110], su1[110], su2[110];
int st1[110], st2[110], max1[110], max2[110];
int pre1[110], pre12[110];
int pre2[110], pre22[110];

int main() {
int n, m, q;
cin >> n >> m >> q;
for (int i = 0; i < 110; i++) { max1[i] = max2[i] = -110;//存该组第i位前2的最大好感度,初始化写最小 } for (int i = 1; i <= n; i++) { for (int j = 1; j <= m; j++) cin >> a[i][j];//1组第i位对2组第j位的好感度
}

for (int i = 1; i <= m; i++) {  
    for (int j = 1; j <= n; j++)  
        cin >> b\[i\]\[j\];//2组第i位对1组第j位的好感度  
}

int x, y, f = 0;  
while (q--) {  
    cin >> x >> y;  
    st1\[x\]++;  
    st2\[y\]++;//判断是否拒绝2次  
    if (st1\[x\] > 2 && st2\[y\] > 2) {//都已经拒绝2次  
        if (a\[x\]\[y\] > max1\[x\] && b\[y\]\[x\] > max2\[y\]) {//判断是否大于拒绝前2次人的好感度  
            if (!su1\[x\] && !su2\[y\]) {//su是表示有木有约会成功过,1就是约过了  
                su1\[x\] = su2\[y\] = 1;  
                cout << x << ' ' << y << "\\n";  
                f = 1;//判断有木有人约会成功过  
            }  
        }  
    }

    pre1\[x\] = pre12\[x\];  
    pre12\[x\] = a\[x\]\[y\];  
    //1组第x个人的拒绝的前2个的好感度,这个时候有新的好感度,所以把第2个好感度  
    //覆盖到第一个,第二个好感度等于新的拒绝的好感度

    pre2\[y\] = pre22\[y\];//与上同理  
    pre22\[y\] = b\[y\]\[x\];

    max1\[x\] = max(pre1\[x\], pre12\[x\]);//存该组第x位拒绝前2位的最大好感度  
    max2\[y\] = max(pre2\[y\], pre22\[y\]);//同理  
}  
if (!f) cout << "PTA is my only love\\n";//没有人约会  
return 0;  

}

7-8 浪漫侧影

左右视其实就是二叉树各层数的第一个和最后一个,所以根据中后序遍历下前序,声明个层数向量存每层的树节点就行,最后根据左右视输出每层的第一个和最后一个节点

#include

typedef long long ll;
const int maxm = 1e5 + 5;
const int infmax = INT_MAX;
const int infmin = INT_MIN;
using namespace std;

int in[250], post[250], maxdepth = 0;
vector v[250];

void pre(int root, int start, int end, int depth) {
if (start > end)
return;
maxdepth = max(maxdepth, depth);
int i = start;
while (i < end && in[i] != post[root]) i++;
v[depth].push_back(post[root]);
pre(root - 1 - (end - i), start, i - 1, depth + 1);
pre(root - 1, i + 1, end, depth + 1);
}

int main() {
int n;
cin >> n;
for (int i = 1; i <= n; i++) cin >> in[i];
for (int i = 1; i <= n; i++) cin >> post[i];

pre(n, 1, n, 1);  
cout << "R:";  
for (int i = 1; i <= maxdepth; i++) cout << ' ' << v\[i\].back();  
cout << "\\n";

cout << "L:";  
for (int i = 1; i <= maxdepth; i++) cout << ' ' << v\[i\].front();  
cout << "\\n";  
return 0;  

}

over,代码写的有点烂,巨巨们轻喷。