@donghanyuan0609
2023-03-18T08:08:00.000000Z
字数 7172
阅读 258
以下提供的 AC 代码可能不是最简的思路和代码实现,仅供参考!
输入一个 n 维向量,求这个向量的模长的平方。
31 2 3
14
#include <stdio.h>#include <stdlib.h>#include <math.h>#include <string.h>#include <ctype.h>int n;int a[1005];int len(){int s = 0;int i;for (i = 0; i < n; i++)s += a[i] * a[i];return s;}int main(){int i;scanf("%d", &n);for (i = 0; i < n; i++)scanf("%d", &a[i]);printf("%d\n", len());return 0;}
要求求的是模长的平方,得到的结果直接就是整数,不需要用浮点数,不需要开平方。
更进一步,对顺序输入的元素求平方和可以不需要数组。更简单的参考代码:
#include <stdio.h>int main() {int n, i, x, s = 0;scanf("%d", &n);for (i = 0; i < n; i++) {scanf("%d", &x);s += x * x;}printf("%d\n", s);return 0;}
给定一个整数 p,保证该数是 2 个质数的乘积(即 ,),求较大的质因子 。
21
7
#include <stdio.h>#include <stdlib.h>#include <math.h>#include <string.h>#include <ctype.h>int main(){int n, i;scanf("%d", &n);for (i = 2; i <= sqrt(n); i++){if (n % i == 0)break;}printf("%d\n", n / i);return 0;}
这道题给的限定条件相当严格,所以其实可用来输入的整数的个数是相当有限的。千万不要担心有不符合 的输入数据。要求输出 可以先找出 (因为 比较小,比较容易找,找的范围是到 即可)。
直接从 2 循环到 n 也是可以的,因为遇到 就 break 了,实际的循环不会真正执行到 以后。
给出一些门课的得分(百分制)和这门课的学分数,求加权平均分。输入为每行 2 个整数,分别表示一门课程的学分数量和百分制得分。输出加权平均分保留 2 位小数。
特别注意:如果总学分数为零,则加权平均为零分( 0.00 )。
6 984 932 88
94.67
#include <stdio.h>#include <stdlib.h>#include <math.h>#include <string.h>#include <ctype.h>int a[105], v[105];int sumv, sum;int main(){int ai, vi;while (scanf("%d%d", &vi, &ai) != EOF){sum += ai * vi;sumv += vi;}if (sumv) printf("%.2lf\n", sum * 1.0 / sumv);else printf("0.00\n");return 0;}
输入数据是没有给学科数量的,也就是输入的行数是 不确定 的,请用 while(scanf(...) != EOF) 输入数据。另外,在本机调试的过程中,当你输入完所有的数据,程序是不会马上有反应的,因为你没有给出n,计算机不知道你输入的数据到底有多少行,所以会一直等着你输入。此时请用 Ctrl+Z 终止输入(控制台会显示一个符号 ^Z,然后再按回车就可以看到输出结果了),^Z 这个符号代表 EOF。
另外注意判断总学分数是否为零。第一次忘了加判断就 WA 了一个点。
以十六进制(大写),2 位一组给出 n 个 8-bit 整数(以一行字符串的形式给出)。
有若干组查询,每个查询给出 和 两个整数,要输出第 个数和第 个数的乘积(十进制)。
输入数据第一行是 ;第二行是一个长度为 的字符串(仅包含数字和大写字母 A-F);第三行是 表示 次查询,接下来 行每行 2 个整数 和 。
对于每次查询,输出一个整数,为第 个数和第 个数的乘积(下标从零开始)
88AE45CF173BB6A2E51 40 22 73 64 5
262201269642322554621505
#include <stdio.h>#include <stdlib.h>#include <math.h>#include <string.h>#include <ctype.h>int hextodec(char x1, char x2){int d1, d2;if (isdigit(x1))d1 = x1 - '0';else if (x1 >= 'A' && x1 <= 'F')d1 = x1 - 'A' + 10;if (isdigit(x2))d2 = x2 - '0';else if (x2 >= 'A' && x2 <= 'F')d2 = x2 - 'A' + 10;return d1 * 16 + d2;}int n, m;int a[10005];int main(){int i;char c1, c2;int x, y;scanf("%d", &n);while (getchar() != '\n');for (i = 0; i < n; i++){c1 = getchar();c2 = getchar();a[i] = hextodec(c1, c2);}scanf("%d", &m);for (i = 0; i < m; i++){scanf("%d%d", &x, &y);printf("%d\n", a[x] * a[y]);}return 0;}
先把输入的长度为 的字符串所表达的 个十六进制整数存入 int 数组,然后处理对于乘积的查询。
给俩字符串,一行一个(均不包含空白字符),判断第一个字符串是不是第二个字符串的子串,如果是的话输出子串最先出现的位置,如果不是子串输出错误信息。
hAnGBeiHangUniversity
BuAAACcoding.cn
Yes:4
Emmm
#include <stdio.h>#include <stdlib.h>#include <math.h>#include <string.h>#include <ctype.h>char key[1005], str[1005];char key2[1005], str2[1005]; //lowercaseint main(){int i;char *ret = NULL;scanf("%s", key);scanf("%s", str);for (i = 0; key[i]; i++)key2[i] = tolower(key[i]);for (i = 0; str[i]; i++)str2[i] = tolower(str[i]);ret = strstr(str2, key2);if (ret != NULL)printf("Yes:%d\n", ret - str2 + 1);elseprintf("Emmm\n");return 0;}
因为题目说了字符串不带空白字符,所以不要用 gets ,优先选用 scanf 。如果用了 gets 一定要检验字符串末尾有没有 '\r' ,否则会错的很惨。 Windows 系统和 Linux 系统的默认换行符不同,想要详细了解可以问助教或者上网查。
用库函数 strstr 匹配子串,要熟悉。此题由于忽略大小写,所以将输入的字符串全部转换为小写再匹配。
给一个 的字符方阵,每个格有地雷或者没有地雷,然后输出一个 的整数方阵,求出每个格子周围的地雷数量(以该格子为中心的九宫格内地雷数量)
我忘了"没有地雷"是什么符号表示了,可能是 '.' 或者 'N' 吧,然后有地雷的符号根据我的AC代码反推回去应该是用 'Y' 表示的。
3 4..Y..Y..Y...
1 2 2 12 3 2 12 2 1 0
#include <stdio.h>#include <stdlib.h>#include <math.h>#include <string.h>#include <ctype.h>int n, m;char mp[105][105];int cnt[105][105];typedef struct Point{int x, y;}Point;Point nil, dir[9] = {{-1,-1}, {-1, 0}, {-1, 1},{0, -1}, {0, 0}, {0, 1},{1, -1}, {1, 0}, {1, 1}};Point mkpt(int x, int y){Point ret;ret.x = x, ret.y = y;return ret;}Point padd(Point a, Point b){Point ret;ret.x = a.x + b.x;ret.y = a.y + b.y;return ret;}int inLim(Point ct){return (ct.x >= 0 && ct.x < n) && (ct.y >= 0 && ct.y < m);}int cntt(Point ct){int i, ret = 0;for (i = 0; i < 9; i++){Point pt = padd(ct, dir[i]);if (inLim(pt) && mp[pt.x][pt.y] == 'Y')ret++;}return ret;}int main(){int i, j;scanf("%d%d", &n, &m);for (i = 0;i < n; i++)scanf("%s", mp[i]);for (i = 0; i < n; i++)for (j = 0; j < m; j++)cnt[i][j] = cntt(mkpt(i, j));for (i = 0; i < n; i++)for (j = 0; j < m; j++)printf("%d%c", cnt[i][j], j == m-1 ? 10 : 32);return 0;}
循环,然后注意一下如何处理边界。
输出的时候每行 m 个整数,中间空格隔开,最后尽量不要留多余的空格(不确定会不会PE)。
给一堆扑克牌的信息,统计当前桌面上现有的牌能凑出几套完整的扑克牌。
多组输入数据
每组输入数据先给一个 n 表示当前桌面上牌的张数,然后每行 2 个整数,分别表示花色(1 到 4 的整数)和牌面(1 到 13 的整数)。输出一个整数表示能凑出来多少张牌。
一副完整扑克牌的标准是 52 张,四种花色每种 13 张。
2131 11 21 31 41 51 61 71 81 91 101 111 122 13521 11 21 31 41 51 61 71 81 91 101 111 121 132 12 22 32 42 52 62 72 82 92 102 112 122 133 13 23 33 43 53 63 73 83 93 103 113 123 134 14 24 34 44 54 64 74 84 94 104 114 124 13
01
#include <stdio.h>#include <stdlib.h>#include <math.h>#include <string.h>#include <ctype.h>int cnt[5][14];int check(){int ret = 0x7FFFFFFF;int i, j;for (i = 1; i <= 4; i++)for (j = 1; j <= 13; j++){if (cnt[i][j] < ret)ret = cnt[i][j];}return ret;}int main(){int T, n;int pat, pid;scanf("%d", &T);while (T--){memset(cnt, 0, sizeof(cnt));scanf("%d", &n);while (n--){scanf("%d%d", &pat, &pid);cnt[pat][pid]++;}printf("%d\n", check());}return 0;}
散列表计数。凑扑克牌是木桶(短板)原理,数量最少的花色+牌面的数量就是答案。
给一个多项式,求其导函数。
输入输出格式参考样例,一次项和零次项均严格按照格式给出。
输出的时候首项如果是正的不要有 + 号。
4*x^4-3*x^2+5*x^1+2*x^0
16*x^3-6*x^1+5*x^0
#include <stdio.h>#include <stdlib.h>#include <math.h>#include <string.h>#include <ctype.h>typedef struct Elem{int k, p;}Elem;Elem F[105];int mxp;Elem mkelm(int kk, int pp){Elem ret;ret.k = kk, ret.p = pp;return ret;}int main(){int k, p, i;int flg = 0;while (scanf("%d*x^%d", &k, &p) == 2){Elem fx = mkelm(k, p);if (k == 0 || p == 0)continue;if (p > mxp) mxp = p;if (F[p].p == 0)F[p].p = p;F[p].k += fx.k;}for (i = mxp; i > 0; i--)//f'{Elem fi = F[i];if (F[i].p != i)continue;fi.k *= fi.p, fi.p--;if (fi.k)printf("%s%d*x^%d", flg && fi.k > 0 ? "+" : "", fi.k, fi.p), flg = 1;}if (!flg)printf("0");return 0;}
就是注意输入的时候用 scanf 控制好格式(每一项的格式为 %d*x^%d ),然后注意一下可能有合并同类项(样例是我现编的,我懒得编那种需要合并的数据了)。输出的时候也是控制好格式就行了。
多项式的题平时上机和练习赛练过两次,主要还是考察 scanf 的格式化输入。
输入俩超大整数( ),可能有前导零,不保证 。输出它们的差。
1000999
1
#include <stdio.h>#include <stdlib.h>#include <math.h>#include <string.h>#include <ctype.h>char s1[505], s2[505];int a[505], b[505];int res[505];int l1, l2, l;int numcmp(){int i;if (l1 > l2)return 1;else if (l1 < l2)return -1;else{for (i = l1; i >= 0; i--){if (a[i] > b[i])return 1;else if (a[i] < b[i])return -1;}}return 0;}int hgint_minus(int *r, int *A, int l1, int *B, int l2)//A - B{int l = l1 > l2 ? l1 : l2;int i;for (i = 0; i < l; i++){r[i] += A[i] - B[i];while (r[i] < 0)r[i] += 10, r[i+1]--;}while (r[l-1] == 0)l--;return l;}int main(){int i;int flg = 0;scanf("%s%s", s1, s2);l1 = strlen(s1), l2 = strlen(s2);for (i = 0; i < l1; i++)a[i] = s1[l1 - i - 1] - '0';for (i = 0; i < l2; i++)b[i] = s2[l2 - i - 1] - '0';while (a[l1 - 1] == 0)l1--;while (b[l2 - 1] == 0)l2--;flg = numcmp();if (flg == 0)l = 1;else if (flg == 1){l = hgint_minus(res, a, l1, b, l2);}else{l = hgint_minus(res, b, l2, a, l1);}if (flg == -1)printf("-");for (i = l - 1; i >= 0; i--)printf("%d", res[i]);return 0;}
高精度模板题,没任何思维难度,倒序存储然后模拟竖式从个位开始算,然后注意借位。
别忘了先比较大小,以及过滤前导零。
这种题直接准备好板子带到考场上抄就行了。
此题为洛谷原题(P1010)。访问链接:https://www.luogu.org/problem/P1010
137
2(2(2)+2+2(0))+2(2+2(0))+2(0)
#include <stdio.h>#include <stdlib.h>#include <math.h>#include <string.h>#include <ctype.h>void solve(int n){int i = 15;int flg = 0;while (i >= 0){int base = (1 << i);if (n & base){switch(i){case 2:printf("%s2(2)", flg ? "+" : ""), flg = 1;break;case 1:printf("%s2",flg ? "+" : ""), flg = 1;break;case 0:printf("%s2(0)",flg ? "+" : ""), flg = 1;break;default:printf("%s2(", flg ? "+" : ""),flg = 1;solve(i);printf(")");}}i--;}}int main(){int n;scanf("%d", &n);solve(n);return 0;}
递归。