又一次周赛题解
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; }
相关文章推荐
- 读CopyOnWriteArrayList有感
- 数据库防注入攻击
- Java 由类的初始化所想到的
- android GridView 使用
- 一个电商项目的Web服务化改造5:面向服务的分层架构设计(有图有真相)
- 一个电商项目的Web服务化改造5:面向服务的分层架构设计(有图有真相)
- (转)Windows下Git使用入门
- mongodb常用分组统计-分组分页求最近时间
- 一个电商项目的Web服务化改造5:面向服务的分层架构设计(有图有真相)
- hdoj1863
- 微信学习_05_图文消息
- UVA 501 - Black Box(二分 + 树状数组 + 离散化)
- CodeForces - 584D Dima and Lisa (素数拆分)数学规律
- Java循环练习:打印图案-1
- 今年我23岁
- leetcode 058 Length of Last Word
- hdu4489(递推)
- POJ 3744 Scout YYF I (矩阵相乘+概率DP)
- optparse模块
- java验证自增