• Codeforces Round #260 (Div. 2) ABCDE


    A题逗比了,没有看到All ai are distinct. All bi are distinct. 其实很水的。。

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <cstring>
     4 #include <algorithm>
     5 using namespace std;
     6 
     7 #define mnx 100002
     8 
     9 
    10 struct latop{
    11     int p, q;
    12     bool operator < ( const latop & b ) const {
    13         return p < b.p;
    14     }
    15 }a[mnx];
    16 int main(){
    17     int n;
    18     scanf( "%d", &n );
    19     for( int i = 0; i < n; i++ ){
    20         scanf( "%d %d", &a[i].p, &a[i].q );
    21     }
    22     sort( a, a + n );
    23     bool flag = 0;
    24     for( int i = 1; i < n; i++ ){
    25         if( a[i].q < a[i-1].q ) flag = 1;
    26     }
    27     if( flag ) puts( "Happy Alex" );
    28     else puts( "Poor Alex" );
    29     return 0;
    30 }
    View Code

    B题找循环节。。循环节是4,然后输入再长的数,也只需要看最后两位,因为100的倍数肯定能够整除4,就看最后两位。。结果又逗比了,数组开小了,最后re了。。太粗心了。。

     1 #include<string>
     2 #include<cmath>
     3 #include<map>
     4 #include<queue>
     5 
     6 using namespace std;
     7 
     8 #define mnx 1000000
     9 #define PI acos(-1.0)
    10 #define ll long long
    11 #define ull unsigned long long
    12 #define inf 0x3f3f3f3f
    13 #define eps 1e-8
    14 #define MP make_pair
    15 #define lson l, m, rt << 1
    16 #define rson m+1, r, rt << 1 | 1
    17 #define mod 2333333
    18 
    19 int a[4] = { 4, 0, 0, 0 };
    20 char ch[mnx];
    21 int main(){
    22     scanf( "%s", &ch );
    23     int n = strlen( ch );
    24     int k = 0;
    25     if( n <= 2 ){
    26         for( int i = 0; i < n; i++ ){
    27             k = k * 10 + ch[i] - '0';
    28         }
    29     //  cout<<k<<endl;
    30         k %= 4;
    31         printf( "%d
    ", a[k] );
    32     }
    33     else{
    34         for( int i = n-2; i < n; i++ ){
    35             k = k * 10 + ch[i] - '0';
    36         }
    37     //  cout<<k<<endl;
    38         k %= 4;
    39         printf( "%d
    ", a[k] );
    40     }
    41     return 0;
    42 }
    View Code

    C题先排序,然后把相同的弄掉,if( b[i] == b[i-1] + 1 )  dp[i] = max( dp[i-2] + sum[i], dp[i-1] ),要么就是选当前这个b[i],然后dp[i]的值就是dp[i-2] + sum[i],要么就选b[i-1],然后dp[i]的值就是dp[i-1];else dp[i] = dp[i] = dp[i-1] + sum[i]; 最后答案就是 dp[cnt]; 具体看代码。。当时写的比较稳妥,多写了一些。。结果还是因为longlong跪了几发,这是后来写的代码

     1 #include<iostream>
     2 #include<cstring>
     3 #include<cstdio>
     4 #include<algorithm>
     5 #include<string>
     6 #include<cmath>
     7 #include<map>
     8 #include<queue>
     9 
    10 using namespace std;
    11 
    12 #define mnx 200000
    13 #define PI acos(-1.0)
    14 #define ll long long
    15 #define ull unsigned long long
    16 #define inf 0x3f3f3f3f
    17 #define eps 1e-8
    18 #define MP make_pair
    19 #define lson l, m, rt << 1
    20 #define rson m+1, r, rt << 1 | 1
    21 #define mod 2333333
    22 
    23 ll a[mnx], b[mnx], sum[mnx], dp[mnx];
    24 int main(){
    25     int n;
    26     scanf( "%d", &n );
    27     for( int i = 1; i <= n; i++ ){
    28         scanf( "%I64d", &a[i] );
    29     }
    30     sort( a + 1, a + 1 + n );
    31     int cnt = 0;
    32     for( int i = 1; i <= n; i++ ){
    33         if( a[i] != b[cnt] ){
    34             ++cnt;
    35             b[cnt] = a[i];
    36             sum[cnt] = a[i];
    37         }
    38         else sum[cnt] += a[i];
    39     }
    40     dp[1] = sum[1]; 
    41     for( int i = 2; i <= cnt; i++ ){
    42         if( b[i] == b[i-1] + 1 ){
    43             dp[i] = max( dp[i-2] + sum[i], dp[i-1] );
    44         }
    45         else{
    46             dp[i] = dp[i-1] + sum[i];
    47         } 
    48     }
    49     cout<<dp[cnt]<<endl;
    50     return 0;
    51 }
    View Code

    D题trie树,不会做。。赛后问了思路,弄了很久才明白。。原本的想法是 trie的根就是必败,然后dfs,第一层就是必胜,遍历到叶子节点,看叶子节点是必败还是必胜,如果叶子节点全是必胜的,说明先手的每次必胜,如果叶子节点全是必败的,说明先手的每次必败,如果叶子节点既有必胜又有必败的,说明先手的每次既能必胜也能必败。。后来发现这样想是错的,如果是abcs,abcab,先手走到c,接下来先手的输赢全部是由后手决定,后手走s,先手输,后手走a,先手赢。。这道题输赢的状态必须由叶子节点开始向根的方向推,看了超哥的代码,开两个bool数组,win[], can[],win数组表示下一步先手开始走,能不能赢,can数组表示下一步先手开始走,能不能输。。所以叶子节点就是win[u] = 0(先手下一步不能走,就不能赢),can[u] = 1(先手下一步不能走,肯定输)。。当一个节点有多个子节点,win[u] = 1就看 win[son[u][i]]里面有没有为0的,否则就是0;can[u] = 1就看can[son[u][i]]里面有没有为0的,否则就是0。。推到根节点的状态。。这样讲有点抽象,可以手动模拟一下 abcs, abcab这种情况。。

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <cstring>
     4 #include <algorithm>
     5 using namespace std;
     6 
     7 #define mnx 100002
     8 
     9 int son[mnx][26], tot;
    10 bool win[mnx], can[mnx];
    11 void insert(char *s) {
    12     int t = 0;
    13     for (int i = 0; s[i]; ++i) {
    14         int c = s[i] - 'a';
    15         if (!son[t][c]) son[t][c] = ++tot;
    16         t = son[t][c];
    17     }
    18 }
    19 void dfs( int u ){
    20     win[u] = 0, can[u] = 1;
    21     bool hav = 0;
    22     for( int i = 0; i < 26; i++ ){
    23         if( son[u][i] ){
    24             dfs( son[u][i] ); hav = 1;
    25         }
    26     }
    27     if( !hav ) return ;
    28     can[u] = 0;
    29     for( int i = 0; i < 26; i++ ){
    30         if( son[u][i] && !win[son[u][i]] ) win[u] = 1;
    31         if( son[u][i] && !can[son[u][i]] ) can[u] = 1;
    32     }
    33 }
    34 char ch[mnx];
    35 int main(){
    36     int n, k;
    37     scanf( "%d%d", &n, &k );
    38     for( int i = 0; i < n; i++ ){
    39         scanf( "%s", ch );
    40         insert( ch );
    41     }
    42     dfs( 0 );
    43     if( win[0] == false ) puts( "Second" );
    44     else{
    45         if( can[0] == true ) puts( "First" );
    46         else puts( (k & 1) ? "First" : "Second" );
    47     }
    48     return 0;
    49 }
    View Code

    E题没时间看,赛后看了一下,发现也不是很难,树的直径和并查集。。比较难处理的就是connect them by a road so as to minimize the length of the longest path in the resulting region  使联通后的区域的直径最小,那么就应该从两条直径的中间点连一条边,使他们联通。。假设要联通两个区域为u,v,直径为val[u], val[v],则联通后的直径应该是 max( val[u], val[v], 1 + ( val[u] - val[u] / 2 ) + ( val[v] - val[v] / 2 );

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <cstring>
     4 #include <algorithm>
     5 using namespace std;
     6 
     7 #define mnx 600005
     8 #define inf 0x3f3f3f3f
     9 
    10 int dis[2][mnx],  fa[mnx], val[mnx];
    11 int vv[mnx], first[mnx], nxt[mnx], e;
    12 bool vis[mnx], in[mnx];
    13 int n, m, query, tot;
    14 void init(){
    15     memset( first, -1, sizeof(first) );
    16     memset( dis, 0x3f, sizeof(dis) );
    17     e = 0;
    18 }
    19 void add( int u, int v ){
    20     vv[e] = v, nxt[e] = first[u], first[u] = e++;
    21 }
    22 int q[mnx];
    23 int bfs( int s, int *dis ){
    24     int head = 0, tail = 0;
    25     q[tail++] = s, dis[s] = 0;
    26     while( head < tail ){
    27         int u = q[head++];
    28         vis[u] = 1;
    29         for( int i = first[u]; i != -1; i = nxt[i] ){
    30             int v = vv[i];
    31             if( dis[v] > dis[u] + 1 ){
    32                 dis[v] = dis[u] + 1;
    33                 q[tail++] = v;
    34             } 
    35         }
    36     }
    37     int id = s, d = dis[s];
    38     for( int i = 0; i < tail; i++ ){
    39         if( dis[q[i]] > d ){
    40             d = dis[q[i]], id = q[i];
    41         }
    42     }
    43     return id;
    44 }
    45 int find( int s ){
    46     if( s != fa[s] ){
    47         fa[s] = find( fa[s] );
    48     }
    49     return fa[s];
    50 }
    51 void treeD( int s ){
    52     int v = bfs( s, dis[0] );
    53     int u = bfs( v, dis[1] );
    54     val[find(u)] = dis[1][u];
    55 }
    56 int main(){
    57     scanf( "%d %d %d", &n, &m, &query );
    58     tot = n;
    59     init();
    60     for( int i = 0; i <= n + query; i++ ){
    61         fa[i] = i;
    62     }
    63     while( m-- ){
    64         int u, v;
    65         scanf( "%d %d", &u, &v );
    66         add( u, v ), add( v, u );
    67         int fu = find( u ), fv = find( v );
    68         fa[fu] = fv;
    69     }
    70     for( int i = 1; i <= n; i++ ){
    71         if( !vis[i] ){
    72             treeD( i );
    73         }
    74     }
    75     while( query-- ){
    76         int tye, u, v;
    77         scanf( "%d", &tye );
    78         if( tye == 1 ){
    79             scanf( "%d", &u );
    80             printf( "%d
    ", val[find(u)] );
    81         }
    82         else{
    83             scanf( "%d%d", &u, &v );
    84             int fu = find( u ), fv = find( v );
    85             if( fu == fv ) continue;
    86             ++tot;
    87             fa[fu] = fa[fv] = tot;
    88             val[tot] = 1 + ( val[fu] - val[fu] / 2 ) + ( val[fv] - val[fv] / 2 );
    89             val[tot] = max( val[tot], val[fu] );
    90             val[tot] = max( val[tot], val[fv] );
    91         }
    92     }
    93     return 0;
    94 }
    View Code
  • 相关阅读:
    php解析word,获得文档中的图片
    小程序 图表 antv f2 的使用
    eslint配置大全
    node 操作word excel
    vue-element-admin
    python中字符串前的r什么意思
    python3 三种字符串(无前缀,前缀u,前缀b)与encode()
    Markdown语法
    Python3 字符串前面加u,r,b的含义
    Python os.walk()
  • 原文地址:https://www.cnblogs.com/LJ-blog/p/3904755.html
Copyright © 2020-2023  润新知