跳至内容
CVBB ACM Team
用户工具
注册
登录
站点工具
搜索
工具
显示页面
修订记录
Copy this page
导出 PDF
反向链接
最近更改
媒体管理器
网站地图
注册
登录
>
最近更改
媒体管理器
网站地图
您在这里:
front_page
»
2020-2021
»
teams
»
namespace
»
serein
»
学习记录
»
语言篇
2020-2021:teams:namespace:serein:学习记录:语言篇:front_page
本页面只读。您可以查看源文件,但不能更改它。如果您觉得这是系统错误,请联系管理员。
//2020-05-05// ====== 第2章 循环结构程序设计 ====== ===== 用计时函数测试程序效率 ===== <code c> #include <time.h> printf("Time used = %.2f\n",(double)clock()/CLOCKS_PER_SEC); </code> ===== 输入输出重定向 ===== * 基础版本 <code c> freopen("input.txt","r",stdin); freopen("output.txt","w",stdout); </code> * 本地版本 <code c> #define LOCAL #ifdef LOCAL freopen("input.txt","r",stdin); freopen("output.txt","w",stdout); #endif </code> * ''%%fopen%%'' 版本 <code c> FILE *fin,*fout; fin = fopen("data.in","rb"); fout = fopen("data.out","wb"); //输入 fscanf(fin,"%d",&x); //输出 fprintf(fout,"%d %d %.3f\n",min,max,(double)s/n); //关闭文件 fclose(fin); fclose(fout); </code> ====== 第3章 数组和字符串 ====== ===== 数组 ===== * 数组赋值函数 ''%%memcpy%%'' <code c> #include<string.h> memcpy(b,a,sizeof(int)*k);//int型 memcpy(b,a,sizeof(double)*k);//double型 memcpy(b,a,sizeof(a));//全部复制 </code> * 数组清零 <code c> #include<string.h> memset(a,0,sizeof(a)); </code> * 蛇形填数(伪代码) <code c> #define maxn 20 int a[maxn][maxn],tot; tot = a[x=0][y=n-1] =1; while(tot< n*n) { while(x+1<n && !a[x+1][y]) a[++x][y] = ++tot; while(y-1>=0 && !a[x][y-1]) a[x][--y] = ++tot; while(x-1>=0 && !a[x-1][y]) a[--x][y] = ++tot; while(y+1<n && !a[x][y+1]) a[x][++y] = ++tot; } </code> * 竖式问题 <code c> #include<stdio.h> #include<string.h> int main() { int count = 0; char s[20]; buf[99]; scanf("%s",s); for(int abc=111; abc <= 999; abc++) for(int de =11; de <= 99; de++) { int x = abc*(de%10), y = abc*(de/10), z = abc*de; sprintf(buf,"%d%d%d%d%d%d"), abc, de, x, y, z); int ok = 1; for(int i = 0; i <strlen(buf); i++) if(strchr(s, buf[i]) == NULL) ok = 0; if(ok) { printf("<%d>\n", ++count); printf("%5d\nX%4d\n-----\n%5d\n%4d\n-----\n%5d\n\n", abc,de,x,y,z); } } printf("The number of solutions = %d\n", count); return 0; } </code> ===== 竞赛题目选讲 ===== * TeX中的引号($UVa272$) <code c> #include<stdio.h> int main(){ int c,q=1; while((c=getchar()) != EOF){ if(c = '"') { printf("%s", q ? "``" ; "''"); q = !q; } else printg("%c", c); } return 0; } </code> 善用常量数组往往能简化代码。定义常量数组时无须指明大小,编译器会计算。 <code c> #include<stdio.h> char s[] = "`1234567890-=QWERTYUIOP[]\\ASDFGHJKL;'ZXCVBNM,./"; int main(){ int i, c; while((c = getchar()) != EOF){ for (i=1; s[i] && s[i]!=c;i++); if(s[i]) putchar(s[i-1]); else putchar(c); } return 0; } </code> 回文词($UVa401$)<HTML></p></HTML> 输入一个字符串,判断它是否为回文串以及镜像串。输入字符串保证不含数字0。(使用常量数组) <code c> #include<stdio.h> #include<string.h> #include<ctype.h> const char* rev = "A 3 HIL JM O 2TUVWXY51SE Z 8 "; const char* msg[] = {"not a palindrome", "a regular palindrome", "a mirrored string", "a mirrored palindrome"}; char r(char ch) { if(isalpha(ch)) return rev[ch - 'A']; return rev[ch - '0' + 25]; } int main() { char s[30]; while(scanf("%s", s) == 1) { int len = strlen(s); int p = 1, m = 1; for(int i = 0; i < (len+1)/2; i++) { if(s[i] != s[len-1-i]) p = 0; if(r(s[i]) != s[len-1-i]) m = 0; } printf("%s -- is %s.\n\n", s, msg[m*2+p]); } return 0; } </code> 猜数字游戏的提示($UVa340$)<HTML></p></HTML> 直接统计可得A,为了求B,对于每个数字(1~9),统计二者出现次数的最小值之和就是该数字对B的贡献。 最后输出A,B-A即可。 <code c> #include<stdio.h> #define maxn 1000 + 10 int main() { int n, a[maxn], b[maxn]; int kase = 0; while(scanf("%d", &n) == 1 && n) { // n=0时输入结束 printf("Game %d:\n", ++kase); for(int i = 0; i < n; i++) scanf("%d", &a[i]); for(;;) { int A = 0, B = 0; for(int i = 0; i < n; i++) { scanf("%d", &b[i]); if(a[i] == b[i]) A++; } if(b[0] == 0) break; // 正常的猜测序列不会有0,所以只判断第一个数是否为0即可 for(int d = 1; d <= 9; d++) { int c1 = 0, c2 = 0; // 统计数字d在答案序列和猜测序列中各出现多少次 for(int i = 0; i < n; i++) { if(a[i] == d) c1++; if(b[i] == d) c2++; } if(c1 < c2) B += c1; else B += c2; } printf(" (%d,%d)\n", A, B-A); } } return 0; } </code> 生成元($UVa1583$) 预处理加散列表。比较简单,代码略。 环状序列($UVa1584$) 用 $ans$ 表示目前为止,字典序最小串在输入串中的起始位置,然后不断更新$ans$,一个值得注意的地方是,对于环形序列,采用他对字符串长度的$mod$值来表示它的相对位置。 <code c> #include<stdio.h> #include<string.h> #define maxn 105 // 环状串s的表示法p是否比表示法q的字典序小 int less(const char* s, int p, int q) { int n = strlen(s); for(int i = 0; i < n; i++) if(s[(p+i)%n] != s[(q+i)%n]) return s[(p+i)%n] < s[(q+i)%n]; return 0; // 相等 } int main() { int T; char s[maxn]; scanf("%d", &T); while(T--) { scanf("%s", s); int ans = 0; int n = strlen(s); for(int i = 1; i < n; i++) if(less(s, i, ans)) ans = i; for(int i = 0; i < n; i++) putchar(s[(i+ans)%n]); putchar('\n'); } return 0; } </code> ===== 注解与习题 ===== 用''%%ASCII%%'' 编码表示字符 进制转换与移位运算符 补码表示法 在大多数的计算机内部,整数采用的是补码表示法。 思考题 必要的存储量:有些时候不一定要开数组即可完成任务。 黑盒测试 算法竞赛一般采用黑盒测试。 超时的原因:效率低;读取数据错误;程序死循环;程序崩溃但退出异常。 在线评测系统 ($Online Judge,OJ$) 西班牙$Valladolid$大学的$UVaOJ$ ====== 第四章 函数和递归 ====== ===== 自定义函数和结构体 ===== * 采用$struct$ 的写法 <code c> struct Point{ double x,y;}; double dist(struct Point a,struct Point b) { return hypot(a.x-b.x, a.y-b.y); } </code> * 采用$typedef$的写法 <code c> typedef struct{ double x,y;}Point; double dist(Point a,Point b) { return hypot(a.x-b.x, a.y-b.y); } </code> 素数判定 ''%%is_prime%%'' 的参数并不是''%%long long%%''型,因为在''%%n%%''很大时,这个函数并不能很快计算出结果。 <code c> int is_prime(int n) { if (n <= 1) return 0; int m = floor(sqrt(n) + 0.5); for (int i = 2; i<= m; i++) if(n % i == 0) return 0; return 1; } </code>
2020-2021/teams/namespace/serein/学习记录/语言篇/front_page.txt
· 最后更改: 2020/05/31 19:49 由
serein
页面工具
显示页面
修订记录
反向链接
Copy this page
导出 PDF
回到顶部