算法竞赛入门经典第三章

string.h
char buff[99],e;
memcpy(b,a,sizeof(int)*k);//int数组a复制k个元素到int数组b
memcpy(b,a,sizeof(a));//全部复制
memset(a,0,sizeof(a));//a数组清零
sprintf(buf,”%d%d”,i,j);//打印到字符数组中
strchr(buf,e);//在buff中查找是否有字符e,e的位置
strlen(buff);//返回buff有效字符的长度,‘\0’之前字符个数
strcpy(a,b);strcmp(a,b);strcat(a,b);//赋值、比较、连接

fgetc(stdin)等价于getchar()//返回int型(因为文件结束符EOF并不是char)
fgets(buf,manx,stdin) //读一行或不超过max-1个字符,最后一个字符’\0’

习题3-1
https://cn.vjudge.net/problem/UVA-1585

#include<iostream>
using namespace std;
int main() {
    int n;
    cin >> n;
    getchar();
    while (n--) {
        char e;
        int cnt = 0, sum = 0;
        while (scanf("%c", &e) && e != '\n') {
            if (e == 'O') ++cnt;
            else {
                sum += (cnt + 1)*cnt>>1;
                cnt = 0;
            }
        }
        sum += (cnt + 1)*cnt >> 1;
        printf("%d\n", sum);
    }
}

习题3-2
https://vjudge.net/problem/UVA-1586
用3-1的输入模式,即一个字符一个字符读遇到\n结束,调教wa
用字符串处理确是对的,很是奇怪

#include<iostream>
#include<cctype>
#include<string>
using namespace std;
int main() {
    int n;
    cin >> n;
    getchar();
    while (n--) {
        char e;
        int cnt = 0;
        double sum = 0.0, per = 0.0;
        string s;
        cin >> s;
        for(int i=0;i<s.size();++i){
            e = s[i];
            if (isalpha(e)) {
                if (!cnt) cnt = 1;
                sum += cnt*per;
                cnt = 0;
                switch (e)
                {
                case 'C':per = 12.01;
                    break;
                case 'H':per = 1.008;
                    break;
                case 'O':per = 16.00;
                    break;
                default:per = 14.01;
                    break;
                }
            }
            else if(isdigit(e))
                cnt = cnt * 10 + e - '0';
        }
        if (!cnt) cnt = 1;
        sum += cnt*per;
        printf("%.3lf\n", sum);
    }
}

3-3习题
https://vjudge.net/problem/UVA-1225

#include<iostream>
using namespace std;
int main() {
    int n;
    cin >> n;
    while (n--) {
        int AA[10] = {};
        int k;
        scanf("%d", &k);
        for (int i = 1; i <= k; ++i) {
            int j = i;
            while (j) {
                ++AA[j % 10];
                j /= 10;
            }
        }
        printf("%d", AA[0]);
        for (int i = 1; i < 10; ++i)
            printf(" %d", AA[i]);
        printf("\n");
    }
}

3-4习题
https://vjudge.net/problem/UVA-455

#include<iostream>
#include<string>
using namespace std;
bool pd(string &s,int k) {
    for (int i = k; i < s.size(); ++i)
        if (s[i] != s[i%k]) return false;
    return true;
}
int main() {
    int n;
    string s;
    cin >> n;
    int cnt = 0;
    while (n--) {
        cin >> s;
        if (cnt++) cout << endl;
        for (int i = 1; i <= s.length(); ++i) {
            if (s.length() % i) continue;       
            if (pd(s, i)) { cout << i << endl; break; }
        }
    }
}

3-5习题
https://vjudge.net/problem/UVA-227

#include<iostream>
#include<string>
using namespace std;
int main() {
    string s[5],str,sss;
    int x, y,tt;
    int flag ;
    int cnt = 0;
    while (getline(cin, s[0]) && s[0] != "Z") {
        ++cnt;
        if (s[0].size() == 4) s[0]+= " ";
        if ((tt = s[0].find(' ')) != string::npos) { x = 0; y = tt; }
        for (int i = 1; i < 5; ++i) {
            getline(cin, s[i]);
            if (s[i].size() == 4) s[i] += " ";
            if ((tt = s[i].find(' ')) != string::npos) { x = i; y = tt; }
        }
        str = "";
        do {
            getline(cin, sss);
            str += sss;
        } while (str.back() != '0');
        flag = 0;
        for (int i = 0; i < str.size() - 1; ++i) {
            switch (str[i])
            {
            case 'A':
                if (!x) { flag = 1; break; }
                swap(s[x][y], s[x - 1][y]);
                x -= 1;
                break;
            case 'B':
                if(x==4) { flag = 1; break; }
                swap(s[x][y], s[x + 1][y]);
                x += 1;
                break;
            case 'L':
                if(!y) { flag = 1; break; }
                swap(s[x][y], s[x][y - 1]);
                y -= 1;
                break;
            case 'R':
                if(y==4) { flag = 1; break; }
                swap(s[x][y], s[x][y + 1]);
                y += 1;
                break;
            default:
                break;
            }
            if (flag) break;
        }
        if (cnt > 1) printf("\n");
        printf("Puzzle #%d:\n", cnt);
        if (flag) printf("This puzzle has no final configuration.\n");
        else {
            for (int i = 0; i < 5; ++i) {
                printf("%c", s[i][0]);
                for (int j = 1; j < 5; ++j)
                    printf(" %c", s[i][j]);
                printf("\n");
            }
        }   
    }
}

3-6习题
https://vjudge.net/problem/UVA-232

#include<iostream>
#include<string>
using namespace std;
struct node {
    int x,y,number;
    node(int a, int b,int c) {
        x = a, y = b,number=c;
    }
    node() = default;
};
node ssta[105];//上无白格
node lsta[105];//左无白格
int stop, ltop;
int main() {
    string s[15];
    int r, c, cnt = 0, nn;
    while (cin >> r && r != 0) {
        ++cnt;
        nn = 0;
        stop = ltop = -1;
        cin >> c;
        for (int i = 0; i < r; ++i)
            cin >> s[i];
        for (int i = 0; i < r; ++i)
            for (int j = 0; j < c; ++j) {
                if (s[i][j] != '*' && (i == 0 || s[i - 1][j] == '*' || j == 0 || s[i][j - 1] == '*')) ++nn;
                if (s[i][j] != '*' && (i == 0 || s[i - 1][j] == '*')) ssta[++stop] = node(i, j, nn);
                if (s[i][j] != '*' && (j == 0 || s[i][j - 1] == '*')) lsta[++ltop] = node(i, j, nn);
            }
        if (cnt != 1) cout << endl;
        printf("puzzle #%d:\nAcross\n", cnt);
        for (int i = 0; i <= ltop; ++i) {
            printf("%3d.", lsta[i].number);
            int k = lsta[i].y;
            while (k < c && s[lsta[i].x][k] != '*')
                printf("%c", s[lsta[i].x][k++]);
            printf("\n");
        }
        printf("Down\n");
        for (int i = 0; i <= stop; ++i) {
            printf("%3d.", ssta[i].number);
            int k = ssta[i].x;
            while (k < r && s[k][ssta[i].y] != '*') 
                printf("%c", s[k++][ssta[i].y]);
            printf("\n");
        }
    }
}

3-7习题
https://vjudge.net/problem/UVA-1368

#include<iostream>
#include<string>
using namespace std;
int main() {
    int n;
    cin >> n;
    string s[55];
    while (n--) {
        int a, b;
        cin >> a >> b;
        for (int i = 0; i < a; ++i)
            cin >> s[i];
        string str;
        int sum=0;
        for (int k = 0; k < b; ++k) {
            int num[4] = {};//ACGT
            for (int i = 0; i < a; ++i) {
                switch (s[i][k])
                {
                case 'A':++num[0]; break;
                case 'C':++num[1]; break;
                case 'G':++num[2]; break;
                case 'T':++num[3]; break;
                default:
                    break;
                }
            }
            if (num[0] >= num[1] && num[0] >= num[2] && num[0] >= num[3]) {
                str += "A"; sum += a - num[0];
            }
            else if (num[1] >= num[0] && num[1] >= num[2] && num[1] >= num[3]) {
                str += "C"; sum += a - num[1];
            }
            else if (num[2] >= num[0] && num[2] >= num[1] && num[2] >= num[3]) {
                str += "G"; sum += a - num[2];
            }
            else {
                str += "T"; sum += a - num[3];
            }
        }
        cout << str << endl << sum << endl;;    
    }
}

3-8
https://vjudge.net/problem/UVA-202
答案要求是结果后面都空一行,我以为是结果之间空一行,唉,体验好差,题目都没说明

#include<iostream>
using namespace std;
int main() {
    int a, b;
    while (cin >> a >> b) {
        int sta[3005], top = 0;//sta[1...3004]
        int vis[3005] = {};//存放访问过的余数的位置+1
        printf("%d/%d = %d.", a, b, a / b);
        a %= b;
        vis[a] = 1;
        while (1) {
            sta[++top] = a * 10 / b;
            a=a * 10 % b;
            //如果vis[a]存在,说明top后面的即是重复的,【vis[a]开始到top】
            if (vis[a]) break;
            vis[a] = top+1;
        }
        for (int i = 1; i <= top; ++i) {
            if (vis[a]<=50 && i == vis[a]) printf("(");
            if (i <= 50) printf("%d", sta[i]);
            if(vis[a]>50 &&i==51) printf("(");
            if (i == 51) printf("...");
        }
        printf(")\n   %d = number of digits in repeating cycle\n\n",top-vis[a]+1);
    }
}

习题3-9
https://vjudge.net/problem/UVA-10340

#include<iostream>
#include<string>
using namespace std;
int main() {
    string s, t;
    while (cin >> s >> t) {
        int i = 0, j = 0;
        for (; i < s.length(); ++i) {
            while (t[j] != s[i]) {
                if (++j > t.length()) break;
            }
            if (j > t.length()) {
                break;
            }
            ++j;
        }
        if (i == s.length())cout << "Yes" << endl;
        else cout << "No" << endl;
    }
}

习题3-10
https://vjudge.net/problem/UVA-1587

#include<iostream>
using namespace std;
int main() {
    int a[6][2],cnt;
    int sta[15], top;//sta[1...14]
    while (cin >> a[0][0] >> a[0][1]) {
        top = 0;
        int vis[10006] = {};
        vis[a[0][0]] = 1; sta[++top] = a[0][0];
        if (!vis[a[0][1]]++) sta[++top] = a[0][1];
        for (int i = 1; i < 6; ++i){
            cin >> a[i][0] >> a[i][1];
            if (!vis[a[i][0]]++)  sta[++top] = a[i][0]; 
            if (!vis[a[i][1]]++)  sta[++top] = a[i][1]; 
        }
        if (top == 1) cout << "POSSIBLE" << endl;//一个数字
        else if (top == 2 && (vis[sta[1]]==8|| vis[sta[1]] == 4)) {//1*1 2个 1*2 4个
            int nn = 0;
            for (int i = 0; i < 6; ++i)
                if (a[i][0] == a[i][1]) ++nn;
            if (nn != 2)cout << "IMPOSSIBLE" << endl;
            else cout << "POSSIBLE" << endl;
        }
        else if (top == 3 && vis[sta[1]]==4 && vis[sta[2]]==4) {//3个数字
            bool flag = true;
            for (int i = 0; i < 6; ++i)
                if (a[i][0] == a[i][1]) { flag = false; break; }
            if(flag) cout << "POSSIBLE" << endl;
            else cout << "IMPOSSIBLE" << endl;
        }
        else
            cout << "IMPOSSIBLE" << endl;
    }
}

习题3-11
https://vjudge.net/problem/UVA-1588

#include<iostream>
#include<string>
#include<algorithm>
using namespace std;
int main() {
    string s, t;
    while (cin >> s >> t) {
        if (s.size() < t.size()) swap(s, t);//t代表短的串
        int gap = 0,gmax=0;
        for (int i = 0; i < s.size()+t.size(); ++i) {
            if (i < t.size()) ++gap;
            if (i >= s.size()) --gap;
            bool flag = true;
            for (int k = 0; k < t.size(); ++k)
                if (i - t.size() + 1 + k >= 0 && i - t.size() + 1 + k <s.size()&& t[k] +s[i - t.size() + 1 + k]-'0'>'3'){
                    flag = false; break;
                }
            if (flag) {
                gmax = max(gap, gmax);
            }
        }
        cout << s.size() + t.size() - gmax << endl;
    }
}

习题3-12
为避免误差,用打表法做,直接求可能会有一些误差导致wa
https://vjudge.net/problem/UVA-11809

#include<iostream>
#include<string>
#include<cmath>
using namespace std;
double X[15][40];
long long int Z[15][40];
int main() {
    string s;
    int E, M;
    for (M = 0; M <= 9; ++M)
        for (E = 1; E <= 30; ++E) {
            double k = log10(2)*(pow(2, E) - 1) + log10(1 - pow(2, -M - 1));
            Z[M][E] = k;
            X[M][E] = pow(10, k - Z[M][E]);
        }
    double A; int B;
    while (cin>>s && s!="0e0") {
        s[s.find('e')] = ' ';
        sscanf(s.c_str(), "%lf %d", &A, &B);
        bool flag = false;
        for (M = 0; M <= 9; ++M) {
            for (E = 1; E <= 30; ++E)
                if (fabs(X[M][E] - A) < 1e-5 && B==Z[M][E]) { flag = true; cout << M << ' ' << E << endl; }
            if (flag) break;
        }
    }

}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值