Codeforces Round#811 Div3
A and B
两道题比较水,懒得做了。
C Minimum Varied Number
暴力搜索即可。但是暴搜也是有技巧的。首先,可以贪心地想,答案数字每一位一定是从小到大的,而且不可能有 \(0\), 有 \(0\) 一定不是最优。
其次,数字不重复,所以最多只有 \(9\) 位数。
那么一次枚举有几位数,然后统计所有结果即可。
点击查看代码
#include <bits/stdc++.h>
using namespace std;
#define N 1000010
#define ll long long
template <class T>
inline void read(T& a){
T x = 0, s = 1;
char c = getchar();
while(!isdigit(c)){ if(c == '-') s = -1; c = getchar(); }
while(isdigit(c)){ x = x * 10 + (c ^ '0'); c = getchar(); }
a = x * s;
return ;
}
int ans = 0;
int n;
void dfs(int now, int last, int sum, int tot, int lim){ // 第多少层,上一位大小,限制位数
if(now > lim){
if(tot == n)
ans = min(ans, sum);
return ;
}
for(int i = last + 1; i <= 9; i++){
dfs(now + 1, i, sum * 10 + i, tot + i, lim);
}
return ;
}
int main(){
// freopen("hh.txt", "r", stdin);
int T; read(T);
while(T--){
ans = 1e9;
read(n);
for(int num = 1; num <= 9; num++){
dfs(1, 0, 0, 0, num);
}
cout << ans << endl;
}
return 0;
}
D. Color with Occurrences
考虑到字符串长度较短,先暴力匹配,将每个字符串的可覆盖区间存下来。
然后,问题就转化为求区间并集且数量最小。(如果某个点没被覆盖,或者说区间连接不上,那么就输出"\(-1\)")。
然后,将区间按照 $$ 排序。贪心的取可以链接的上的区间中,\(r\) 最靠右的那个即可。
点击查看代码
#include <bits/stdc++.h>
using namespace std;
#define N 1000010
#define ll long long
template <class T>
inline void read(T& a){
T x = 0, s = 1;
char c = getchar();
while(!isdigit(c)){ if(c == '-') s = -1; c = getchar(); }
while(isdigit(c)){ x = x * 10 + (c ^ '0'); c = getchar(); }
a = x * s;
return ;
}
string h;
string s[11];
int n;
struct node{
int l, r;
int id;
bool operator < (const node& a) const{
return l < a.l || (l == a.l && r < a.r);
}
} t[N];
vector <node> G[101];
vector <node> ans;
map <string, int> g;
int main(){
// freopen("hh.txt", "r", stdin);
int T; read(T);
while(T--){
for(int i = 1; i <= 100; i++)G[i].clear();
g.clear();
ans.clear();
cin >> h;
read(n);
for(int i = 1; i <= n; i++)
cin >> s[i];
for(int i = 1; i <= n; i++) g[s[i]] = i;
int len = h.length();
for(int i = 0; i < len; i++){
string tmp;
for(int j = i; j < len; j++){
tmp += h[j];
if(g.count(tmp)){
G[i + 1].push_back((node){i + 1, j + 1, g[tmp]});
}
}
}
int sum = 0;
int nowl = 0, nowr = 0;
while(nowr <= len){
node maxn = {0, -1, 0};
for(int i = nowl; i <= nowr + 1; i++){
for(auto it : G[i]){
if(it.r > maxn.r){
maxn = it;
}
}
}
if(maxn.r <= nowr){
break;
}
else{
nowl = maxn.l;
nowr = maxn.r;
ans.push_back(maxn);
sum++;
}
}
if(nowr < len){
puts("-1");
}
else{
printf("%d\n", sum);
for(auto it : ans){
printf("%d %d\n", it.id, it.l);
}
}
}
return 0;
}