codeforces round #612解题报告A~D
Posted zxytxdy
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了codeforces round #612解题报告A~D相关的知识,希望对你有一定的参考价值。
codeforces round #612解题报告A~D
A. Angry Students
- 分析一下题意其实就可以发现是找(A)后面最长连续的(P)有多少个。
#include<bits/stdc++.h>
using namespace std;
void solve()
{
int n;
cin >> n;
string str;
cin >> str;
int ans = 0;
for(int i = 0; i < n; i++)
{
if(str[i] == 'A')
{
for(int j = i+1; j < n; j++)
{
if(str[j] == 'A') break;
else ans = max(ans, j - i);
}
}
}
cout << ans << endl;
}
int main()
{
int T;
scanf("%d", &T);
while(T--) solve();
return 0;
}
B. Hyperset
- 这题有个好处就是他的Feature只有三个,所以可以枚举两个字符串,确定出第三个字符串,之后看看有没有另一个就行。
#include<bits/stdc++.h>
using namespace std;
const int maxn = 1500 + 10;
typedef long long ll;
string s[maxn];
int n, k;
map<string, int> mp;
int main()
{
scanf("%d%d", &n, &k);
for(int i = 1; i <= n; i++)
{
cin >> s[i];
mp[s[i]]++;
}
int all = 'S' + 'E' + 'T';
int ans = 0;
for(int i = 1; i <= n; i++)
{
for(int j = i+1; j <= n; j++)
{
string tmp = "";
for(int t = 0; t < k; t++)
{
if(s[i][t] == s[j][t])
tmp += s[i][t];
else tmp += all - s[i][t] - s[j][t];
}
ans += mp[tmp];
}
} cout << ans / 3 << endl;
return 0;
}
C. Garland
- 这题只用关注奇偶性就行。
- 设(f(i,j,k,2))表示考虑到第(i)位剩(j)个奇数和(k)个偶数,上一个数的奇偶性是什么(0表示奇数,1表示偶数),得到的最小值。
- 如果当前位置为奇数:
- (f(i,j,k,0)=min(f(i-1,j-1,k,0),f(i-1,j-1,k,1)+1)).
- 偶数同理。
- 对于(0)的位置,奇数偶数都可以。
#include<bits/stdc++.h>
using namespace std;
const int maxn = 1e2 + 10;
int a[maxn], n;
int f[maxn][maxn][maxn][3];
int odd, even;
int main()
{
scanf("%d", &n);
for(int i = 1; i <= n; i++) scanf("%d", &a[i]);
even = n/2, odd = n-even;
memset(f, 0x3f, sizeof(f));
f[0][0][0][0] = f[0][0][0][1] = 0;
int k;
for(int i = 1; i <= n; i++)
{
if(a[i])
{
if(a[i]&1)
{
for(int j = 1; j <= i; j++)
{
k = i - j;
f[i][j][k][1] = min(f[i-1][j-1][k][1], f[i-1][j-1][k][0]+1);
}
}
else
{
for(int j = 0; j < i; j++)
{
k = i - j;
f[i][j][k][0] = min(f[i-1][j][k-1][0], f[i-1][j][k-1][1]+1);
}
}
}
else
{
for(int j = 1; j <= i; j++)
{
k = i - j;
f[i][j][k][1] = min(f[i-1][j-1][k][1], f[i-1][j-1][k][0]+1);
}
for(int j = 0; j < i; j++)
{
k = i - j;
f[i][j][k][0] = min(f[i-1][j][k-1][0], f[i-1][j][k-1][1]+1);
}
}
}
cout << min(f[n][odd][even][0], f[n][odd][even][1]) << endl;
return 0;
}
D. Numbers on Tree
题意:
给定一颗有根树,节点编号为(1)到(n),每个节点上有一个值(a_i),一个人计算了(c_i),这个(c_i)表示子树中所有节点(j),有(a_j<a_i)的数量。
现在只知道有一棵树,知道节点的父亲节点和他的(c_i),构造原始的(a_i)。
思路:
- 先考虑一个节点(x),他的子节点为叶子节点,假设说他有(n)个子节点,他的(c_i=m)。
- 这种情况就相对容易一些了,直接构造(m)个儿子为(1,2,3,...,m),然后自己为(m+1),剩下的儿子为(m+2,...,n+1)。
- 那么对于节点(x)的父亲节点,那么往中间找个位置插一下就行。
#include<bits/stdc++.h>
using namespace std;
const int maxn = 2e3 + 10;
int n, c[maxn], rt, a[maxn];
vector<int> son[maxn];
vector<int> dfs(int x)
{
vector<int> ans, res; ans.clear();
for(auto y : son[x])
{
vector<int> tmp = dfs(y);
for(auto t : tmp)
ans.push_back(t);
}
if(ans.size() < c[x]) {puts("NO"); exit(0);}
for(int i = 0; i < c[x]; i++) res.push_back(ans[i]);
res.push_back(x);
for(int i = c[x]; i < ans.size(); i++) res.push_back(ans[i]);
return res;
}
int main()
{
scanf("%d", &n);
for(int i = 1, f, w; i <= n; i++)
{
scanf("%d%d", &f, &w);
c[i] = w; son[f].push_back(i);
} vector<int> ans = dfs(0);
puts("YES");
for(int i = 0; i < ans.size(); i++)
a[ans[i]] = i+1;
for(int i = 1; i <= n; i++)
printf("%d ", a[i]);
return 0;
}
以上是关于codeforces round #612解题报告A~D的主要内容,如果未能解决你的问题,请参考以下文章
Codeforces Round #612 (Div. 2)
Codeforces Round #616 (Div. 2)解题报告
Codeforces Round #615(Div.3)解题报告
Codeforces Educational Round 81 解题报告