zoukankan      html  css  js  c++  java
  • CF875C National Property

    题目描述

    给定一些字符串,其中字母用数字表示,并且初始是小写的。你可以把一些小写字母改成大写,但同时你要把所有同种字母全部改成大写。问是否能经过一些操作使得最终的字符串序列满足按字典序升序排列。如果能,则需要输出方案。

    题解

    可以把每个字母看成点,有大写和小写俩种情况。若对于俩个相邻的字符串来说,字典序大小的比较其实是第一个不相同的字符,找到那个不相同的位置,可能不存在,假设存在设为x,若i的字典序大于i - 1的,则这俩行的x位置的大小写情况应该相同。若i-1的字典序大于i的,则说明必然是i-1在x的字符是大写,在i的x字符必然是小写,这题其实看似像扩展域并查集,但在并查集上无法体现&关系,只能2-SAT。

     1 #include <bits/stdc++.h>
     2 #define MAX 200005
     3 using namespace std;
     4  
     5 int n, m, cnt, tot;
     6 int len, lst[MAX], a[MAX], col[MAX];
     7 int head[MAX], Next[MAX*2], vet[MAX*2];
     8  
     9 void add(int x, int y){
    10     cnt++;
    11     Next[cnt] = head[x];
    12     head[x] = cnt;
    13     vet[cnt] = y;
    14 }
    15  
    16 int low[MAX], dfn[MAX], vis[MAX], T;
    17 stack<int> s;
    18 void tarjan(int x){
    19     low[x] = dfn[x] = ++T;
    20     vis[x] = true;
    21     s.push(x);
    22     for(int i = head[x]; i; i = Next[i]){
    23         int v = vet[i];
    24         if(!dfn[v]){
    25             tarjan(v);
    26             low[x] = min(low[x], low[v]);
    27         }
    28         else if(vis[v]){
    29             low[x] = min(low[x], dfn[v]);
    30         }
    31     }
    32     if(low[x] == dfn[x]){
    33         tot++;
    34         int t = -1;
    35         while(t != x){
    36             t = s.top();
    37             s.pop();
    38             vis[t] = false;
    39             col[t] = tot;
    40         }
    41     }
    42 }
    43  
    44 int main()
    45 {
    46     cin >> m >> n;
    47     for(int i = 1; i <= m; i++){
    48         int t;
    49         scanf("%d", &t);
    50         for(int j = 1; j <= t; j++){
    51             scanf("%d", &a[j]);
    52         }
    53         for(int j = 1; j <= min(len, t); j++){
    54             if(lst[j] < a[j]){
    55                 add(a[j] + n, lst[j] + n);
    56                 add(lst[j], a[j]);
    57                 break;
    58             }
    59             else if(lst[j] > a[j]){
    60                 add(lst[j], lst[j] + n);
    61                 add(a[j] + n, a[j]);
    62                 break;
    63             }
    64             if(j == min(len, t) && len > t){
    65                 puts("No");
    66                 return 0;
    67             }
    68         }
    69         len = t;
    70         for(int j = 1; j <= t; j++) lst[j] = a[j];
    71     }
    72     
    73     for(int i = 1; i <= n*2; i++){
    74         if(!dfn[i]) tarjan(i);
    75     }
    76     for(int i = 1; i <= n; i++){
    77         if(col[i] == col[i+n]){
    78             puts("No");
    79             return 0;
    80         }
    81     }
    82     
    83     puts("Yes");
    84     int ans = 0;
    85     for(int i = 1; i <= n; i++){
    86         if(col[i] > col[i+n]){
    87             ans++;
    88         }
    89     }
    90     cout << ans << endl;
    91     for(int i = 1; i <= n; i++){
    92         if(col[i] > col[i+n]){
    93             printf("%d ", i);
    94         }
    95     }
    96     
    97     return 0;
    98 }
    View Code
  • 相关阅读:
    告别ThinkPHP6的异常页面, 让我们来拥抱whoops吧
    ThinkPHP6 上传图片代码demo
    【ThinkPHP6:从TP3升级到放弃】1. 前言及准备工作
    PHP数字金额转换大写金额
    提高PHP开发效率, PhpStorm必装的几款插件
    5分钟弄懂Docker!
    GitHub 上排名前 100 的 IOS 开源库简介
    GitHub 上排名前 100 的 Android 开源库简介
    android线程消息传递机制——Looper,Handler,Message
    Android Activity:四种启动模式,Intent Flags和任务栈
  • 原文地址:https://www.cnblogs.com/xwdzuishuai/p/14032129.html
Copyright © 2011-2022 走看看