Codeforces Round #138 (Div. 2)
来源:互联网 发布:淘宝手机端搭配套餐 编辑:程序博客网 时间:2024/06/01 07:41
第一次Codeforces.做出三题,但是第二题,有个细节没考虑到。Rating:1500+151=1651,于是下次继续Div2吧。>_<!
A:
题目给出平行六面体的连接一个顶点的三个面的面积,输出这个12条棱的和。
只要枚举下一条边,求出另外的两条边就行了。
#include<cstdio>#include<iostream>#include<cstdlib>using namespace std;int a,b,c;bool work(int a,int b,int c){ int j,k; for (int i = 1;i*i<=a;++i) if (a % i == 0) { j = a / i; if (b % j == 0) { k = b / j; if (c == i * k ) { cout << (i+j+k)*4 << endl; return 1; } } } return 0;}int main(){ cin >> a >> b >> c; if (work(a,b,c) || work(a,c,b) || work(b,a,c) || work(b,c,a) || work(c,a,b) || work(c,b,a) ) { return 0; } return 0;}
B:
给数组a,包含n个元素,人物是找到inclusion segment[l,r].使得,al al+1 … ar,包含了正好k个不同的数字。Definclusion : if there is no segment [x, y]satisfying the property and less thenm inlength, such that 1 ≤ l ≤ x ≤ y ≤ r ≤ n然后r-l不一定要最小。
直接上代码:
#include<iostream>#include<cstdio>using namespace std;int n,k,d,cnt,left = 1;;int a[200000];int flag[200000];int initial = -1;int main(){ cin >> n >> k; cnt = 0; for (int i = 1;i<=100000;++i) flag[i] == 0; for (int i = 0;i<n;++i) { scanf("%d",&d); a[i] = d; if (flag[d] == 0) { ++cnt; ++flag[d]; if (cnt == k) { int l = 0; while (l+1<i && flag[a[l]]>1) { --flag[a[l]];++l; } printf("%d %d\n",l+1,i+1); return 0; } }else ++flag[d]; } printf("-1 -1\n"); return 0;}
C:
定义括号字符串为包含[] & () 的字符串。然后题目费劲地想表达的是找到一个最大的满足匹配的子串,使得”[”的数目最多,并输出这个子串。
用栈来做,遇到左括号压栈,遇到右括号弹出。然后用个计数器,累加,每当出现不匹配的情况,就清空计数器,很容易顺便求出最大值和这个子串。
但是不能处理这种情况([]([]
为了处理这种情况,我把[]的这个计数器统计到(只有当有右括号匹配(时,[]才会被统计。
实现起来只是添加了一个和栈内元素对应的数组来记录计数。
#include<iostream>#include<cstdio>#include<string>using namespace std;string s;int stack[200000];int value[200000];int n;int transfer(char c){ if (c == '(') return 2; if (c == '[') return 1; if (c == ']') return -1; if (c == ')') return -2;}int top = 0;int bj = 0;int main(){ cin >> s; n = s.size(); int now = 0,ans = 0; for (int i = 0;i<s.size();++i) { if (transfer(s[i]) >0 ) { stack[top] = transfer((s[i])); value[top] = now; now = 0; ++top; } else{ if (top == 0 || transfer(s[i]) + stack[top-1] != 0) { top = 0; now = 0; continue; } --top; now += value[top]; if (transfer(s[i]) == -1) ++now; if (now > ans ) { ans = now; bj = i; } } } cout << ans << endl; int rs = 0,ls = 0,lc = 0,rc = 0; if (ans != 0) { int tp = bj; while (tp>=0) { if (s[tp] == ']') ++ rs; if (s[tp] == '[') ++ ls; if (s[tp] == '(') ++ lc; if (s[tp] == ')') ++ rc; if (ls == ans && rs == ans && lc == rc) { cout << string(s,tp,bj-tp+1) << endl; return 0; } --tp; } } return 0;}
D:
得到两个字串S和T,考虑一类子串X=sk1sk2…skn.满足k1<k2<…<kn.
判断是否对于所有的I, X=sk1sk2…skn,X=T 并且 Kj=i.
计算出Left[i] i=0..T.size(),表示S中的所有X中能够匹配T[i]的极左。
同理计算出Right[i]表示能够匹配T[i]的极右。然后题目就变成了一些线段能否覆盖所有线段。
可以用类似括号匹配的方法来做。
#include<iostream>#include<cstdio>#include<algorithm>#include<string>using namespace std;const int N = 200005;string S,T;int occ[256];int markL[N],markR[N];int main(){ cin >> S >> T; int l,r; r = 0; for (l = 0;l<S.size();++l) { if (r<T.size() && S[l] == T[r]) markL[l]++, ++r; } if (r<T.size()) { puts("No"); return 0; } r = T.size()-1; for ( l = S.size()-1;l>=0;--l) { if (r>=0 && S[l] == T[r]) markR[l]-- , --r; }// for (int i = 0;i<S.size();++i) cout << markL[i] << " " << markR[i] << endl; for (int i = 0;i<S.size();++i) { occ[S[i]] += markL[i]; if (occ[S[i]] == 0) { puts("No"); return 0; } occ[S[i]] += markR[i]; } puts("Yes"); return 0;}
E:
给出一个数组n元数组a。我们队数组a进行k次操作。操作定义如下。
1、
2、把s赋给a。
输出k次操作后的数组a。
因为(1 ≤ n ≤ 2000,0 ≤ k ≤ 109)所以不能用矩阵乘法(n太大了).
推出公式:
要推出这个公式也不难,先不要考虑a,然后观察操作后Si的值(这个值有aj的系数组成).
#include<iostream>#include<cstdio>using namespace std;#define LL long longconst LL MOD = 1000000007;//const LL MOD = 7;LL myDiv(int x){ LL res = 1; LL tmp = x; int y = MOD-2; while (y>0) { if (y % 2 == 1) { res *= tmp; res %= MOD; } y/= 2; tmp *= tmp; tmp %= MOD; } return res;}LL getC(int n,int k){ LL res = 1; for (int i = 1;i<=k;++i) { res = res * (n-i+1); res %= MOD; res = res * myDiv(i); res %= MOD; } return res;}int n,k;LL ar[2005],Ans[2005];int C[2005];int main(){ cin >> n >> k ; for (int i = 0;i<n;++i) scanf("%d",&ar[i]); if (k==0) { for (int i = 0;i<n;++i) Ans[i] = ar[i]; } else { for (int i = 0;i<=n;++i) { C[i] = getC(k-1+i,i); // cout << i << " " << C[i] << endl; } for (int i = 0;i<n;++i) { Ans[i] = 0; for (int j = 0;j<=i;++j) { Ans[i] += ar[j] * C[i-j];// cout << C[i-j] << endl; Ans[i] %= MOD; } // printf("\n"); } } for (int i = 0;i<n-1;++i) { printf("%d ",Ans[i]); } printf("%d\n",Ans[n-1]); return 0;}
- Codeforces Round #138 (Div. 2)
- Codeforces Round #138 (Div. 2)
- Codeforces Round #138 (Div. 2)
- Codeforces Round #138 (Div. 2)
- Codeforces Round #138 (Div. 2) A题
- Codeforces Round #138 (Div. 2) A. Parallelepiped
- Codeforces Round #138 (Div. 2) B. Array
- Codeforces Round #138 (Div. 1)
- Codeforces Round #102 (Div. 2)
- Codeforces Round #103 (Div. 2)
- Codeforces Round #103 (Div. 2)
- Codeforces Round #104 (Div. 2)
- Codeforces Round #105 (Div. 2)
- Codeforces Round #105 (Div. 2)
- Codeforces Round #107 (Div. 2)
- Codeforces Round #108 (Div. 2)
- Codeforces Round #110 (Div. 2)
- Codeforces Round #122 (Div. 2)
- http数据包概要记录
- WPF 获取ListView中列添加LinkButton按钮,点击按钮的当前行的ID值
- 求N!末尾有多少个0
- ADT20新建项目Android Support library not installed问题
- C++继承
- Codeforces Round #138 (Div. 2)
- 【无限互联】iOS开发视频教程—2.5 iPhone开发之OC运算符和表达式
- 关于爱情
- js jquery数组介绍
- Android:Native C源码(NDK)如何使用sqlite3进行编程?
- wamp设置内网访问和mysql如何设置登录密码
- proc源码解析(一)--proc文件系统的内容
- JUnit4中级篇
- linux vi 删除命令