又一次周赛题解

来源:互联网 发布:桂树焉知泰山之高的焉 编辑:程序博客网 时间:2024/04/30 12:26

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;}
0 0
原创粉丝点击