由于报了竞赛所以苦逼的在寒假也要写题目,开一篇记录一下寒假写的部分算法题
蛇形填数 在nn的矩形中填入1,2,3,……,n n,要求填成蛇形 如4*4方阵:
1 2 3 4 10 11 12 1 9 16 13 2 8 15 14 3 7 6 5 4
大致的思路就是将全部值初始化为0,从最右边开始的值为1,开始向下填数 在填数的时候就直接判断在不超过界限的情况下值是否为0 是0就填,不是的话就进入下一个循环开始向左填数,以此类推
代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 #include <stdio.h> int main () { int array [100 ][100 ] = {0 }; int x,y; int n,num = 1 ; scanf ("%d" ,&n); x = 0 , y = n-1 ; array [x][y] = 1 ; while (num < n*n) { while (array [x+1 ][y] == 0 && x < n-1 ) array [++x][y] = ++num; while (array [x][y-1 ] == 0 && y > 0 ) array [x][--y] = ++num; while (array [x-1 ][y] == 0 && x > 0 ) array [--x][y] = ++num; while (array [x][y+1 ] == 0 ) array [x][++y] = ++num; } for (size_t x = 0 ; x < n; x++) { for (size_t y = 0 ; y < n; y++) { printf ("%-5d " ,array [x][y]); } printf ("\n" ); } }
排列 用1,2,3,…,9组成3个三位数abc,def和ghi,每个数字恰好使用一次 要求abc:def:ghi=1:2:3。按照“abc def ghi”的格式输出所有解,每行一个解
排列组合然后判断比值虽然没有什么问题,但是这样实在不大划算(虽然但是不管怎么说其实能用也不用纠结那么多的XD) 所以一开始就直接以a作为基数,b=2a、c=3a,然后再用布尔数组判断是否使用了1-9的全部数字就行了
代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 #include <stdio.h> _Bool array (_Bool num[]) { for (size_t i = 1 ; i < 10 ; i++) if (num[i] == 0 ) return 1 ; return 0 ; } int main () { int a,b,c; for (int i = 111 ; i < 999 ; i++) { _Bool num[10 ] = {0 }; a = i; b = i * 2 ; c = i * 3 ; if (c > 999 ) break ; for (; c > 0 ; a /= 10 , b /= 10 , c /= 10 ) { num[a % 10 ] = 1 ; num[b % 10 ] = 1 ; num[c % 10 ] = 1 ; } if (array (num) == 1 ) continue ; else printf ("%d %d %d\n" ,i,i * 2 , i * 3 ); } }
数数字 把整数顺次写在一起,数一数0~9各出现过多少次
这个题是初中学C的时候被难住的一题,当时完全不知道超出long范围的数要怎么处理,再看的时候简直不要太简单
1 2 3 4 5 6 7 8 9 10 11 12 13 #include <stdio.h> int main () { int count[10 ] = {0 }; char num; while ((num = getchar()) != '\n' ) count[num - 48 ]++; for (size_t i = 0 ; i < 10 ; i++) printf ("%d" ,count[i]); }
周期字符串 如果一个字符串可以由某个长度为k的字符串重复多次得到,则称该串以k为周期 例如,abcabcabcabc以3为周期 输入一个长度不超过80的字符串,输出其最小周期
代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 #include <stdio.h> #include <string.h> _Bool compared (char ch[100 ], int len , int i) { for (size_t n = i; n < len; n++) { if (ch[n] != ch[n % i]) return 0 ; } return 1 ; } int main () { char ch[100 ]; int len; _Bool ok; scanf ("%s" ,ch); len = strlen (ch); for (size_t i = 1 ; i < len; i++) { if (len % i == 0 ) ok = compared(ch, len, i); else continue ; if (ok) { printf ("%d" ,i); break ; } } }
谜题 有一个5*5的网格,其中恰好有一个格子是空的,其他格子各有一个字母。 一共有4种指令:A, B, L, R,分别表示把空格上、下、左、右的相邻字母移到空格中。 输入初始网格和指令序列(以数字0结束),输出指令执行完毕后的网格。如果有非法指令,应输出“This puzzle has no final configuration.”
首先读取文件中的字符,前面用的是fscanf函数一个一个读取祖父,但是遇到后面的换行符就不大好处理,而用fscanf函数读取字符串的话遇到空格就会直接停下,所以最好用的还是fgets函数。 然后用getchar来从缓冲区读取字符,配合字符数组来进行操作。
代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 #include <stdio.h> #define NUM 5 int main () { char str[10 ][10 ]; char put; int x = 2 , y = 1 ; FILE *fp; fp = fopen("test.in" ,"rb" ); for (size_t i = 0 ; i < NUM; i++) fgets(str[i],10 ,fp); while ((put = getchar()) != '0' ) { if (put == 'A' ) str[x][y] = str[x-1 ][y],x--; else if (put == 'B' ) str[x][y] = str[x+1 ][y],x++; else if (put == 'L' ) str[x][y] = str[x][y-1 ],y--; else if (put == 'R' ) str[x][y] = str[x][y+1 ],y++; else {printf ("This puzzle has no final configuration\n" ); break ;} } str[x][y] = ' ' ; for (size_t i = 0 ; i < NUM; i++) { for (size_t j = 0 ; j < NUM; j++) printf ("%c" ,str[i][j]); printf ("\n" ); } }
DNA序列 输入m个长度均为n的DNA序列,求一个DNA序列,到所有序列的总Hamming距离尽量小。 两个等长字符串的Hamming距离等于字符不同的位置个数,例如,ACGT和GCGA的Hamming距离为2(左数第1, 4个字符不同)。 输入整数m和n(4≤m≤50, 4≤n≤1000),以及m个长度为n的DNA序列(只包含字母A,C,G,T),输出到m个序列的Hamming距离和最小的DNA序列和对应的距离。 如有多解,要求为字典序最小的解。例如,对于下面5个DNA序列,最优解为TAAGATAC。 TATGATAC TAAGCTAC AAAGATCC TGAGATAC TAAGATGT
用三重循环先把每个数组的总hamming距离计数,然后把最小的hamming距离数组的下标记录下来,由于题目要求多解时输出最小字典,所以在外部定义一个函数记录字符串的大小。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 #include <stdio.h> int compare (char a[], char b[], int mark, int last, int n) { int count1 = 0 ,count2 = 0 ; for (size_t i = 0 ; i < n; i++) { count1 += a[i]; count2 += b[i]; } if (count1 < count2) return mark; else return last; } int main () { char dna[50 ][1000 ]; int count[50 ] = {0 }; int m,n; scanf ("%d %d" ,&m,&n); for (size_t i = 0 ; i < m; i++) scanf ("%s" ,dna[i]); for (size_t x = 0 ; x < m; x++) for (size_t y = 0 ; y < m; y++) { if (x == y) continue ; for (size_t z = 0 ; z < n; z++) if (dna[x][z] != dna[y][z]) count[x]++; } int min = count[0 ]; int index = 0 ; for (int i = 1 ,last_min; i < m; i++) { if (count[i] < min) { min = count[i]; last_min = i; index = i; } else if (count[i] == min) { index = compare(dna[i], dna[last_min], i, last_min, n); last_min = index; } } printf ("%s\n" ,dna[index]); }
八皇后问题 在8*8的宫格中,放置8个皇后,8个皇后之间所占据的位置中八个方位不能有其他皇后
这题要用到回溯算法,在递归中发现错误回退上一步再尝试下一个解法下面的代码是我从网上找的参考,并不是我自己写的,等写出来后再把自己的放上来(2.19日)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 #include <stdio.h> #include <stdlib.h> #define length 8 int count = 0 ; int ms[length][length] = {0 };int isTrue (int a, int b) { int t; for (t=a-1 ; t>=0 ; t--) { if (ms[t][b] == 1 ) return 0 ; } for (t=b-1 ; t>=0 ; t--){ if (ms[a][t] == 1 ) return 0 ; } int m, n; for (m=a-1 ,n=b-1 ; m>=0 &&n>=0 ; m--,n--) { if (ms[m][n] == 1 ) return 0 ; } for (m=a-1 ,n=b+1 ; m>=0 &&n<length; m--,n++) { if (ms[m][n] == 1 ) return 0 ; } return 1 ; } void print () { count++; printf ("%d:\n" , count); int a, b; for (a=0 ; a<length; a++) { for (b=0 ; b<length; b++) { if (ms[a][b] == 0 ) { printf ("* " ); } else if (ms[a][b] == 1 ) { printf ("# " ); } } printf ("\n" ); } printf ("\n\n" ); } void fun (int m) { if (m == length) { print(); return ; } int i; for (i=0 ; i<length; i++) { if (isTrue(m, i)) { ms[m][i] = 1 ; fun(m+1 ); ms[m][i] = 0 ; } } } int main (void ) { fun(0 ); return EXIT_SUCCESS; }
最后 十三届蓝桥杯二等奖
没想到我这么摸也能拿个二等奖,不过如果不是因为c语言标准问题浪费好多时间应该可以搞个一等奖的,有点可惜了。