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

// 程序3-1 逆序输出
#include 
#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 
#include 
#define MAXN 1000 + 10
int 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 
#include 
#define MAXN 20
int 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=0 && !a[x][y-1]) a[x][--y] = ++tot;
        while(x-1>=0 && !a[x-1][y]) a[--x][y] = ++tot;
        while(y+1
#include 
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 
#include 
#include  // 判断字符属性,转换字符
#define MAXN 5000+10
char 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 
#include 
#include 
#define MAXN 5000+10
char 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 max){
                max = j*2+1; // 记录当前最大值
                x = p[i-j]; // 记录原串起始(结束)位置
                y = p[i+j];
            }
        }
        for(j=0; i-j>=0&&i+j+1 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 
#include 
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 
#include  // 重要
#include 
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 
#include 
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 
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 
#include 
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 
#define MAXN 10
using namespace std;

char s[MAXN][MAXN];
int main(void)
{
    int n;
    cin >> n;
    for(int i=0; i> 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 
#include 
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 
#include 
#include 
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 
#include 
#include 
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;
}

转载于:https://www.cnblogs.com/yanweicode/p/4356295.html

你可能感兴趣的:(算法竞赛入门经典-第三章源代码)