算法竞赛入门经典-第三章源代码

来源:互联网 发布:留学低龄化数据 编辑:程序博客网 时间:2024/04/30 13:05
// 程序3-1 逆序输出#include <stdio.h>#define MAXN 100+10 // 保险int a[MAXN]; // 比较大的数组应尽量声明在main函数外int main(void){    int i, x, n=0;    while(scanf("%d", &x)==1)        a[n++] = x;    for(i = n-1; i >= 1; i--)        printf("%d ", a[i]);    printf("%d\n", a[0]); // 输出n个整数只需要n-1个空格,所以分两行输出    return 0;}// 程序3-2 开灯问题#include <stdio.h>#include <string.h>#define MAXN 1000 + 10int a[MAXN]; // 数组模拟操作int main(void){    int i, j, n, k, first = 1;    memset(a, 0, sizeof(a));    scanf("%d%d", &n, &k); // 两个循环位置可以互换    for(i = 1; i <= k; i++) // 遍历每个人        for(j = 1; j <= n; j++) // 分析每盏灯            if(j%i == 0)                a[j] = !a[j];    for(i = 1; i <= n; i++)        if(a[i])        {            if(first) first = 0; // 避免输出多余空格            else printf(" ");            printf("%d", i);        }    printf("\n");    return 0;}// 程序3-3 蛇形填数#include <stdio.h>#include <string.h>#define MAXN 20int a[MAXN][MAXN];int main(void){    int n, x, y, tot = 0;    scanf("%d", &n);    memset(a, 0, sizeof(a));    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;    } // 使用++i不影响后面的数据    for(x = 0; x < n; x++){        for(y = 0; y < n; y++)            printf("%5d", a[x][y]);        printf("\n");    }    return 0;}// 程序3-4 竖式问题#include <stdio.h>#include <string.h>int main(void){    int i, ok, abc, de, x, y, z, count = 0;    char s[20], buf[100];    scanf("%s", s); // 用字符串存放整数,便于利用字符串函数    for(abc = 111; abc <= 999; abc++) // 先穷举abc/de,后剔除不符合的        for(de = 11; de <= 99; de++){ // 为什么从11/111开始?            x = abc*(de%10);            y = abc*(de/10);            z = abc*(de);            sprintf(buf, "%d%d%d%d", abc, de, x, y, z); // 创建“集合”            ok = 1; // printf输出到屏幕,fprintf输出到文件,sprintf输出到字符串            for(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;}// 程序3-5 最长回文子串(1)#include <stdio.h>#include <string.h>#include <ctype.h> // 判断字符属性,转换字符#define MAXN 5000+10char buf[MAXN], s[MAXN];int main(void){    int i, j, k, ok, n, m=0, max=0;    fgets(buf, sizeof(s), stdin);    n = strlen(buf);    for(i = 0; i < n; i++)        if(isalpha(buf[i]))            s[m++] = toupper(buf[i]);    for(i = 0; i < m; i++)        for(j = i; j < m; j++){ // 枚举所有子串(首i->尾j)            ok = 1; // "判断题"            for(k = i; k<=j&&ok!=0; k++)                if(s[k] != s[i+j-k]) // 判断回文串                    ok = 0;            if(ok && j-i+1>max)                max = j-i+1;        }    printf("max = %d\n", max);    return 0;}// 程序3-6 最长回文子串(2) // 迭代式开发#include <stdio.h>#include <string.h>#include <ctype.h>#define MAXN 5000+10char buf[MAXN], s[MAXN];int p[MAXN];int main(void){    int i, j, x, y, n, m = 0, max = 0;    fgets(buf, sizeof(s), stdin); // 读入一行字符串    n = strlen(buf);    for(i = 0; i < n; i++) // 预处理字符串简化任务        if(isalpha(buf[i])){            p[m] = i; // m对应新串序号,i对应原串序号            s[m++] = toupper(buf[i]);        }    for(i = 0; i < m; i++)    { // i为中间位置,j为“半径”,注意对j的限制(由特殊例子推导一般)        for(j=0; i-j>=0&&i+j<m; j++){// 奇数序列            if(s[i-j] != s[i+j])                break;            if(j*2+1 > max){                max = j*2+1; // 记录当前最大值                x = p[i-j]; // 记录原串起始(结束)位置                y = p[i+j];            }        }        for(j=0; i-j>=0&&i+j+1<m; j++){// 偶数序列            if(s[i-j] != s[i+j+1])                break;            if(j*2+2 > max){                max = j*2+2;                x = p[i-j];                y = p[i+j+1];            }        }    }    for(i = x; i <= y; i++)        printf("%c", buf[i]);    printf("\n");    return 0;}// 习题3-1 分数统计(stat)#include <iostream>#include <cstring>using namespace std;int main(void){    int a[101], n; // 用数组记录次数    memset(a, 0, sizeof(a));    while(cin >> n)        ++a[n];    int max = a[0];    for(int i = 1; i < 101; ++i)        if(a[i] > max)            max = a[i];    for(int i = 0; i < 101; ++i)        if(a[i] == max)            cout << i << " ";    return 0;}// 习题3-1 分数统计(stat)#include <iostream>#include <algorithm> // 重要#include <cstring>using namespace std;const int MAXN = 1000+10;bool cmp(double a, double b){    return 100*a<100*b;}int main(void){    int a[MAXN];    double mark[MAXN];    memset(a, 0, sizeof(a));       int n = 0;    while(cin >> mark[n++]); // 记录数据及数目    sort(mark, mark+n, cmp); // 排序预处理       int cnt = 1;    for(int i = 1; i < n; i++){ // 记录mark次数        if(100*mark[i] == 100*mark[i-1]) // 为什么后面的与前面的比较?考虑最后一个数!            cnt++;        else{            a[i-1] = cnt; // 标记到最后一个相同的数            cnt = 1;        }    }    a[n-1] = cnt;    int max = a[0];    for(int i = 1; i < n; i++) // 寻找最大次数        if(a[i] > max)            max = a[i];    for(int i = 0; i < n; i++) // 从小到大依次输出        if(a[i] == max)            cout << mark[i] << " ";       return 0;}// 习题3-2 单词的长度(word)#include <iostream>#include <cstring>using namespace std;int main(void){    string line;    int cnt, word;    cnt = word = 0;    while(cin >> line){        ++word;        cnt += line.size();    }    cout << 1.0*cnt/word << endl;    return 0;}// 习题3-3 乘积的末3位(product)#include <iostream>using namespace std;int main(void){    int cheng, ge, shi, bai, n;    cheng = 1;    while(cin >> n){        ge = cheng*(n%10);        shi = 10*cheng*((n/10)%10);        bai = 100*cheng*(n/100);        cheng = ge + bai + shi;    // “小学生”算术        cheng %= 1000;    }    cout << cheng << endl;    return 0;}// 习题3-4 计算器(calculator)#include <cstdio>#include <iostream>using namespace std;const int MAXN = 100+10;int main(void){    char word[MAXN];    int a, b, i;    char c;    while(1){        i = 0;        while(c=getchar(), c!='\n') // 巧用逗号运算符            if(c!=' ' && c!='\t')                word[i++] = c;        sscanf(word, "%d%c%d", &a, &c, &b);        switch(c){            case '+': cout << a+b << endl; break;            case '-': cout << a-b << endl; break;            case '*': cout << a*b << endl; break;        }    }    return 0;}// 习题3-5 旋转(rotate)#include <iostream>#define MAXN 10using namespace std;char s[MAXN][MAXN];int main(void){    int n;    cin >> n;    for(int i=0; i<n; i++){        for(int j=0; j<n; j++){         cin >> s[i][j];            cout << s[i][j] << " ";        }        cout << endl;    }    for(int j=n-1; j>=0; j--){        for(int i=0; i<=n-1; i++)            cout << s[i][j] << " ";        cout << endl;    }    return 0;}// 习题3-6 进制转换1(base1)#include <iostream>#include <cstring>using namespace std;int main(void){    int n, b, i, a[100];    while(cin >> n >> b){        i = 0;        memset(a, 0, sizeof(a));        while(n != 0)        {            a[i++] = n % b;            n /= b;        }        for(int j=i-1; j>=0; j--)            cout << a[j];        cout << endl;    }    return 0;}// 习题3-7 进制转换2(base2)#include <iostream>#include <cstring>#include <cmath>using namespace std;const int MAXN = 5000+10;int main(void){    int a[MAXN], b, n;    while(cin >> b >> n)    {        int cnt = 0;        memset(a, 0, sizeof(a));        while(n)        {            a[cnt++] = n%10;            n /= 10;        }        int sum = 0;        for(int i = 0; i < cnt; ++i)            sum += a[i]*pow(b, i);        cout << sum << endl;    }    return 0;}// 习题3-8 手机键盘(keyboard)#include <iostream>#include <string>#include <cstdlib>using namespace std;int main(void){    string word;    while(cin >> word){        for(int i = 0; i < word.size(); ++i){            int t = (word[i]-'a'+1)%3;            if(abs(word[i]-word[i-1]) < 3 && i != 0)                cout << word[i-1] << (t?t:3);            else                cout << word[i] << (t?t:3);        }        cout << endl;    }    return 0;}

0 0
原创粉丝点击