又一次周赛题解

a题

http://acm.hust.edu.cn/vjudge/contest/view.action?cid=114608#problem/A
这道题是我提供的,我曾经写过题解,链接如下:
http://blog.csdn.net/zjy2015302395/article/details/51232557

c题

http://acm.hust.edu.cn/vjudge/contest/view.action?cid=114608#problem/C
大意是做矩阵乘法中一共算了多少次乘法运算,明显是栈的运用,第一次做的时候用了struct node【s-‘A’】取元素,队列里是char型s,如果都是数据内的可以,如果一个是算过的新加去的,另一个是数据内的也可以,但遇到(a*b) * (c*d)的时候这个算法就是失败的,然后想到直接放结构体类型的队列就ok了,scanf(~)不加~会tle。。

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

    struct Matrix
    {
        int a, b;
    } m[26];

    stack<Matrix> s;

    int main()
    {
        int n;
        cin >> n;
        for(int i = 0; i < n; i++)
        {
            char name[11110];
            scanf("%s",name);
            int k = name[0] - 'A';
            scanf("%d%d",&m[k].a,&m[k].b);
        }
        char ss[11000];
        while(scanf("%s",ss) != EOF)
        {
            int len = strlen(ss);

            int ans = 0,i;
            for( i = 0; i < len; i++)
            {
                if(isalpha(ss[i]))
                    s.push(m[ss[i] - 'A']);

                else if(ss[i] == ')')
                {
                    Matrix m2 = s.top();
                    s.pop();
                    Matrix m1 = s.top();
                    s.pop();
                    if(m1.b != m2.a)
                    {
                        printf("error\n");
                        break;
                    }
                    ans += m1.a * m1.b * m2.b;
                    Matrix kk;
                    kk.a = m1.a;
                    kk.b = m2.b;
                    s.push(kk);
                }
            }
            if(i == len)
             printf("%d\n", ans);
        }

        return 0;
    }

e、f、g题

三个题是佳神出的bc的题,当时上课没有做上,这回补上。。。

e题大意:

对于每个字符串找他含有k个不同字母的子串个数,(子串(substring)为连续,子序列(subsequence)不连续)

思路:由于连续,假设从0到n刚好满足k个不同字母这个要求,那么0到n+1一直到0到strlen(s)-1这些子串一定都满足条件,就是len-n个,那可不可能首位的字母其实在0到n中也有呢,那去掉首位的字母也一定成立,所以我们设立head,初始化为0,那么如果首字母出现过,就接着往后移head直到少于k个。

#include <cstdio>
#include <iostream>
#include <cstring>
const int maxn = 1e6;
using namespace std;

char s[maxn];

int main()
{
    int T;
    scanf("%d",&T);
    while (T--)
    {
        int k,num = 0,head = 0;
        int book[30];
        long long ans = 0;
        memset(book,0,sizeof (book));

        scanf("%s%d",s,&k);
        int len = strlen(s);

        for (int i = 0 ; i < len ;i++)
        {
            if( ! book[s[i]-'a'] )
                num++;
            book[s[i]-'a']++;
            while(num >= k)
            {
                ans += len-i;
                book[s[head]-'a']--;
                if(!book[s[head]-'a'])
                    num--;
                head++;
            }
        }

        cout << ans <<endl;
    }
}

f题大意:

对已知矩阵做运算,分别有行列交换,行加减,列加减。

思路:正常做会超时,设置四个数组,分别模拟操作,最后输出的时候原来的二维数组是没有动的,只是改变了输出顺序而已(加上该加的数)

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

int a[1010][1010];
int A[1005],B[1005],C[1005],D[1005];

int main()
{
    int T,n,m,q;
    scanf("%d",&T);
    while(T--)
    {
        scanf("%d%d%d",&n,&m,&q);
        memset(A,0,sizeof(A));
        memset(B,0,sizeof(B));
        memset(C,0,sizeof(C));
        memset(D,0,sizeof(D));
        for(int i=1;i<=n;i++)
            A[i]=i;
        for(int i=1;i<=m;i++)
            B[i]=i;
        for(int i=1;i<=n;i++)
            for(int j=1;j<=m;j++)
                scanf("%d",&a[i][j]);
        while(q--)
        {
            int i ,x, y;
            scanf("%d%d%d",&i,&x,&y);
            if(i==1)
                swap(A[x],A[y]);
            if(i==2)
                swap(B[x],B[y]);
            if(i==3)
                C[A[x]]+=y;
            if(i==4)
                D[B[x]]+=y;
        }
        for(int i=1;i<=n;i++)
            for(int j=1;j<=m;j++)
                printf("%d%c",a[A[i]][B[j]]+C[A[i]]+D[B[j]],(j==m) ? '\n':' ');
    }
    return 0;
 }

g题大意:

好多灯泡通过开关在三个颜色中不断变化,最右面的每次变一个颜色,倒数第二个每三次变一个,倒数第三个每9次变一个颜色,以此类推,输出n次后各个灯泡的颜色

思路。。。不多解释了

#include <iostream>
#include <cstdio>

using namespace std;

int main()
{
    int T;
    scanf("%d",&T);

    while (T--)
    {
        int m;
        long long n;
        scanf("%d%I64d",&m,&n);

        int a[35];

        for(int i = m ; i > 0;i--)
        {
            a[i] = n%3;
            n /= 3;
        }
        for (int i = 1; i <= m ;i++)
        {
            if(a[i] == 0)
                printf("R");
            else if(a[i] == 1)
                printf("G");
            else
                printf("B");
        }
        cout <<endl;
    }
    return 0;
}

你可能感兴趣的:(又一次周赛题解)