USACO Section 1.2解题报告

T1

命名那个数字 Name That Number

题意

每个数字上都有一些字母,类似手机按键的。给出一堆名字和一串数字,判断根据这些数字能按到这些名字中的哪些。

思路

搜索每种数字的可能,再判断。
或一个一个名字的判断,看看能不能从这些数字中按出。
这里我用了搜索,效率比第二种方法低。

代码

#include<map>
#include<cstdio>
#include<string>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;

int a[15];
int l, k, ans;
char ch[15];
map<string, bool> f;
char letter[11][3]={{},{},{'A','B','C'},{'D','E','F'},{'G','H','I'},{'J','K','L'},{'M','N','O'},{'P','R','S'},{'T','U','V'},{'W','X','Y'}};
string p[5000], str;

void dfs(string ans, int len) {
    if(len == l + 1) {//判断有没有这个名字
        if(!f[ans]) return;
        else p[++k] = ans;
        return; 
    }
    for(int i = 0; i < 3; i++)//搜索这个数字的三个字母 
        dfs(ans + letter[a[len]][i], len + 1);
}

int main()
{
    scanf("%s", ch + 1);
    l = strlen(ch + 1);
    while (cin>>str) f[str] = 1;
    for(int i = 1; i <= l; i++) a[i] = ch[i] - '0';
    dfs("", 1);
    if(!k) printf("NONE");
    else {
        sort(p, p + 1 + k);
        for(int i = 1; i <= k; i++) cout<<p[i]<<endl;
    }
}

T2

挤牛奶Milking Cows

题意

N N N个人会在 x ∼ y x\sim y xy的时间给牛挤奶,求最长的没人挤奶的一段和有人挤奶的一段。

思路

我们可以用前缀和的思想。在 a [ x ] + 1 a[x]+1 a[x]+1 a [ y ] − 1 a[y]-1 a[y]1,统计前缀和时就可以求出这时有没有人挤奶,然后就可以求出答案。

代码

#include<cstdio>
#include<algorithm>
using namespace std;

int N, s = 1000001, e, ans1, ans2, t1, t2;
int a[1000001];

int main() {
    scanf("%d", &N);
    int x, y;
    for (int i = 1; i <= N; i++) {
        scanf("%d %d", &x, &y);
        a[x]++;
        a[y]--;
        s = min(s, x);
        e = max(e, y);
    }
    for (int i = s; i <= e; i++) {
        a[i] += a[i - 1];
        if (a[i]) {//此时有人挤奶就要清空最长没人挤奶的答案
            ans2 = max(t2, ans2);
            t2 = 0;
            t1++;//同时统计有人挤奶的答案
        }
        else {//同上
            ans1 = max(t1, ans1);
            t1 = 0;
            t2++;
        }
    }
    printf("%d %d", ans1, ans2);
}

T3

方块转换 Transformations

题意

给出两个矩阵,判断通过 7 7 7中操作能不能把第一个转成第二个。操作详见题目。

思路

7 7 7个判断就好了。

代码

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;

int N;
char a[11][11], b[11][11];
char c;

int check1() {
    for (int i = 1; i <= N; i++) 
        for (int j = 1; j <= N; j++)
            if (a[i][j] != b[j][N - i + 1]) return 0;
    return 1;
}

int check2() {
    for (int i = 1; i <= N; i++) 
        for (int j = 1; j <= N; j++)
            if (a[i][j] != b[N - i + 1][N - j + 1]) return 0;
    return 1;
}

int check3() {
    for (int i = 1; i <= N; i++) 
        for (int j = 1; j <= N; j++)
            if (a[i][j] != b[N - j + 1][i]) return 0;
    return 1;
}

int check4() {
    for (int i = 1; i <= N; i++)
        for (int j = 1; j <= N; j++) 
            if (a[i][N - j + 1] != b[i][j]) return 0;
    return 1; 
}

int check5() {
    int f = 0;
    for (int i = 1; i <= N; i++)
        for (int j = 1; j <= N / 2; j++) 
            swap(a[i][N - j + 1], a[i][j]);
    if (check1()) f = 1;
    else if (check2()) f = 1;
    else if (check3()) f = 1;
    for (int i = 1; i <= N; i++)
        for (int j = 1; j <= N / 2; j++) 
            swap(a[i][N - j + 1], a[i][j]);
    return f;
}

int check6() {
    for (int i = 1; i <= N; i++)
        for (int j = 1; j <= N; j++)
            if (a[i][j] != b[i][j]) return 0;
    return 1;
}

int main() {
    scanf("%d", &N);
    for (int i = 1; i <= N; i++)
        scanf("%s", a[i] + 1);
    for (int i = 1; i <= N; i++) 
        scanf("%s", b[i] + 1);
    if (check1()) printf("1");
    else if (check2()) printf("2");
    else if (check3()) printf("3");
    else if (check4()) printf("4");
    else if (check5()) printf("5");
    else if (check6()) printf("6");
    else printf("7");
}

T4

回文平方数 Palindromic Squares

题意

给出一个进制。求出 1 ∼ 300 1\sim 300 1300中的平方在这个进制下是回文串的数。

思路

转换进制然后判断是不是回文串。

代码

#include<cstdio>
#include<cstring>
using namespace std;

int B;

void print(int N, int a[]) {
    for (int i = N; i >= 1; i--)
        if (a[i] > 9) putchar(a[i] + 55);
        else printf("%d", a[i]);
}

void check(int s) {
    int N1 = 0, N = 0, f = 1, x = s * s;
    int a[11], b[11];
    for (int t = x; t; t /= B) a[++N] = t % B;//进制转换
    for (int i = 1; i <= N; i++) if (a[i] != a[N - i + 1]) f = 0;//判断回文
    if (f) {
        for (; s; s /= B) b[++N1] = s % B;
        print(N1, b);//输出这个数
        printf(" ");
        print(N, a);//它的平方
        printf("\n");
    }
}

int main() {
    scanf("%d", &B);
    for (int i = 1; i <= 300; i++) check(i);
}

T5

双重回文数 Dual Palindromes

题意

找到前 N N N个大于 S S S的双重回文数。
定义:双重回文数为一个数在至少两种进制下都为回文数的数。

思路

根据定义来枚举判断。

代码

#include<cstdio>
#include<cstring>
using namespace std;

int N, S, ans;

int check(int s, int B) {//判断在B进制下是否问回文数
    int N = 0, f = 1;
    int a[101];
    for (; s; s /= B) a[++N] = s % B;
    for (int i = 1; i <= N; i++) if (a[i] != a[N - i + 1]) f = 0;
    return f;
}

int main() {
    scanf("%d %d", &N, &S);
    for (int i = S + 1; ans != N; i++) {//枚举
        int f = 0;
        for (int j = 2; j <= 10 && f != 2; j++) if (check(i, j)) f++;//找两个进制
        if (f == 2) {
            ans++;
            printf("%d\n", i);
        }
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值