Educational Codeforces Round 103 (Rated for Div. 2)
A. K-divisible Sum
原题信息
解题思路
AC代码
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N = 100010;
int main()
{
int t; cin >> t;
while (t -- )
{
static LL n, k;
scanf("%lld%lld", &n, &k);
k = (n / k + (n % k != 0)) * k;
// printf("N=%lld, k=%lld\n", n, k);
cout << (k / n + (k % n != 0)) << endl;
}
return 0;
}
B. Inflation
原题信息
解题思路
AC代码
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N = 100010;
int n, k;
LL p[N], b[N];
int main()
{
int t; cin >> t;
while (t -- )
{
scanf("%d%d", &n, &k);
for (int i = 0; i < n; i ++ )
scanf("%lld", &p[i]);
b[0] = p[0];
for (int i = 1; i < n; i ++ )
b[i] = b[i - 1] + p[i];
LL res = 0;
for (int i = 1; i < n; i ++ )
{
res = max(res, 100LL * p[i] / k - b[i - 1] + (100LL * p[i] % k != 0));
}
cout << res << endl;
}
return 0;
}
C. Longest Simple Cycle
原题信息
解题思路
AC代码
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N = 100010;
const LL INF = 0x3f3f3f3f3f3f3f3f;
int n, k;
LL res;
LL a[N], b[N], c[N];
int main()
{
int t; cin >> t;
while (t -- )
{
res = 0;
// input
scanf("%d", &n);
for (int i = 1; i <= n; i ++ ) scanf("%lld", &c[i]);
for (int i = 1; i <= n; i ++ ) scanf("%lld", &a[i]);
for (int i = 1; i <= n; i ++ ) scanf("%lld", &b[i]);
for (int i = 1; i <= n; i ++ )
if (a[i] > b[i])
swap(a[i], b[i]);
LL tmp, pre = -INF;
for (int i = 2; i <= n; i ++ )
{
if (a[i] == b[i])
tmp = c[i] + 1;
else
tmp = max(c[i] + b[i] - a[i] + 1, c[i] + pre - (b[i] - a[i] - 1));
res = max(res, tmp);
pre = tmp;
}
cout << res << endl;
}
return 0;
}
D. Journey
原题信息
解题思路
AC代码
#include <bits/stdc++.h>
using namespace std;
const int N = 301010;
int f_l[N], f_r[N];
int ans[N];
char s[N];
int n;
int main()
{
int t; cin >> t;
while (t -- )
{
scanf("%d", &n);
scanf("%s", s + 1);
// left
f_l[1] = 1;
for (int i = 2; i <= n; i ++ )
if (s[i] != s[i - 1])
f_l[i] = f_l[i - 1] + 1;
else
f_l[i] = 1;
// right
f_r[n] = 1;
for (int i = n - 1; i >= 1; i -- )
if (s[i] != s[i + 1])
f_r[i] = f_r[i + 1] + 1;
else
f_r[i] = 1;
// 初始化并计算结果
memset(ans, 0, sizeof ans);
for (int i = 1; i <= n; i ++ )
if (s[i] == 'R')
ans[i - 1] += f_r[i];
else
ans[i] += f_l[i];
cout << ans[0] + 1;
for (int i = 1; i <= n; i ++ )
printf(" %d", ans[i] + 1);
puts("\n");
}
return 0;
}
E. Pattern Matching
原题信息
解题思路
倘若题目的要求,变一下,变成 rearrange 后的 pattern 在 mt[j] 的位置上是与 str[j] 匹配的,那么本题就变成了一个 二分图匈牙利算法的问题
显示对 m 个 str进行排序,按照他们的 mt进行排序,最后看每个mt需要满足的匹配要求,连向可以连接的 pattern,这样二分图就构建完成,直接跑一边匈牙利算法即可。
这是我之前一直读错的题意 ,绝了。
AC代码
#include <bits/stdc++.h>
using namespace std;
const int BASE = 27, M = 27 * 27 * 27 * 27 + 10;
const int N = 100010, K = 7;
int _hash[M], char_num[258]; // _hash 需要开辟的数组
int n, m, k;
char _str[N][K]; // n 个 pattern
char pattern_match[K]; // dfs查询 m 个 str可以匹配的 pattern 可能
char str[5]; int mt; // m 个询问
vector<int> idx_ret; // 记录返回的编号
int h[N], e[M * 5], ne[M * 5], idx;
bool flag = true; // 全局变量,记录是否可以
int ind[N];
int res[N]; // 存储最终的排序结果
// 计算字符串hash的数值
int Cal(char *s)
{
int ret = 0;
for (int i = 0, base = 1; i < k; i ++, s ++)
{
ret += base * char_num[*s];
base = base * BASE;
}
return ret;
}
// 第一个是 str, 第二个是 pattern,可以带有_
bool Match(char *s, char *pa)
{
for (int i = 0; i < k; i ++ )
{
if (*s == *pa || *pa == '_' || *s == '_')
{
s ++; pa ++;
continue;
}
return false;
}
return true;
}
void GetIdx(char *s, int cnt)
{
if (cnt == k)
{
if (Match(str, pattern_match))
{
if (_hash[Cal(pattern_match)] != -1)
{
idx_ret.push_back(_hash[Cal(pattern_match)]);
}
}
return;
}
else
{
pattern_match[cnt] = *s;
GetIdx(s + 1, cnt + 1);
pattern_match[cnt] = '_';
GetIdx(s + 1, cnt + 1);
}
}
void add(int x, int y)
{
e[idx] = y, ne[idx] = h[x], h[x] = idx ++;
}
void topsort()
{
int cur_idx = 1;
queue<int> que;
for (int i = 1; i <= n; i ++ )
{
if (ind[i] == 0)
que.push(i);
}
int u, v;
/// printf("TOPSORT:\n");
while (que.size())
{
u = que.front(); que.pop();
res[cur_idx ++] = u;
/// printf("%d, ", u);
for (int i = h[u]; ~i; i = ne[i])
{
v = e[i];
ind[v] --;
if (ind[v] == 0)
que.push(v);
}
}
/// cout << endl;
/// printf("n=%d, curidx=%d\n", n, cur_idx);
flag = (cur_idx == n + 1);
/// cout << flag << endl;
}
int main()
{
// _hash initial
memset(_hash, -1, sizeof _hash);
for (int i = 'a'; i <= 'z'; i ++ )
char_num[i] = i - 'a';
char_num['_'] = 26;
// edge list initial
memset(h, -1, sizeof h);
idx = 1;
// input and build string hash
cin >> n >> m >> k;
for (int i = 1; i <= n; i ++ )
{
scanf("%s", _str[i]);
_hash[Cal(_str[i])] = i;
}
/*
cout << 27 * 27 * 27 * 27 - 1 << endl;
cout << Cal("abc_") << endl;
cout << Cal("____") << endl;
cout << Cal("aaaa") << endl;
return 0;
*/
// ind initial
memset(ind, 0, sizeof ind);
for (int i = 1; flag && i <= m; i ++ )
{
scanf("%s%d", str, &mt);
if (!Match(str, _str[mt]))
{
puts("NO");
return 0;
}
else
{
idx_ret.clear();
GetIdx(str, 0);
/// printf("\t*J:%d\n", i);
for (int j = 0; flag && j < idx_ret.size(); j ++)
{
if (mt != idx_ret[j])
{
add(mt, idx_ret[j]);
ind[idx_ret[j]] ++;
}
/// cout << idx_ret[j] << ", ";
}
/// puts("");
}
}
//
if (!flag)
{
/// printf("BEGIN\n");
puts("NO");
}
else
{
topsort();
if (!flag)
{
puts("NO");
}
else
{
puts("YES");
cout << res[1];
for (int i = 2; i <= n; i ++ )
printf(" %d", res[i]);
puts("");
}
}
return 0;
}