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;
}

posted @ 2022-10-20 13:51  雪之下,树之旁  阅读(21)  评论(0编辑  收藏  举报