您的位置:首页 > 其它

又一次周赛题解

2016-04-30 17:16 309 查看

a题

http://acm.hust.edu.cn/vjudge/contest/view.action?cid=114608#problem/A

这道题是我提供的,我曾经写过题解,链接如下:

/article/10397977.html

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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: