zoukankan      html  css  js  c++  java
  • Codeforces Round #460 (Div 2)

    这场比赛实在北京camp期间打得,当时是说和室友一起开车。比赛开场我先交了C题,过了pretest后紧接着就被hack。发现坑点之后,告诉了室友,室友便开始了强盗生涯,怒hack近10发。

    这场比赛让我发现:1. CF其实组队打也蛮好玩的,但是不太道德,以后我也尽量不会组队开车了; 2. 肯定是有很多组队上分选手存在的,而且组队上分非常高效;3. hack加的分可以远远超过一道题目的分,上分必学。

    整体看这次题目还是比较简单的,都可以做。可惜最后一题一开始没有想清楚,忽略了策略图中的环,最后没能在赛中提交。

    题目链接:http://codeforces.com/contest/919

    A.

    B. Perfect Numbers

    题意:如果一个正整数各个数位之和为10,那么就称这个数是perfect的。让你找出第k(<= 10000)大的perfect数。

    观察:猜测10000个perfect数不会很大,所以直接爆搜就好了。

    方法:从1(或者19)开始向上枚举正整数,并且暴力判断。

    code:略

    思考:如果k很大(比如<= 1e18) 该怎么求呢?)

    C. Seat Arrangements

    题意:给你一个n*m的0/1矩阵,让你找同行或同列连续的k个0,问你有多少种方法。n,m,k <= 2000

    观察:行和列可以分开做。好像滑动窗口,前缀和等等都可以做,需要注意的是k=1时,需要特判。

    方法:二维前缀和/滑动窗口/多次一维前缀和

    code:略

    WA:没有考虑k=1的特殊情况。

    D. Substring

    题意:给你一个n个点,m条边的有向图,(n, m <= 3e5) 每个点标有一个字母。对于图中的一条路,它的权值是路径上出现次数最多的字母的个数。让你找出最大的权值。

    观察:如果有环的话,那么最大的权值就是+inf。不然的话就是一个DAG上的DP。

    方法:比赛里是先判环,然后倒着dp的。其实可以用正向拓扑排序,边dp,边判断是否有环。

    code: 略

    E. Congruence Equation

    题意:看题吧。。

    观察:p很小,不超过1e6+3,可以枚举的样子。然后既可以从p入手,考虑到a^x mod p 有周期T,且phi(p) = p-1是一个(也可以O(p-1)暴力的求出周期),而且p为素数,a%p != 0,则有a^(n+T) mod p == a^(n-T) mod p == a^n mod p == a^(n mod T) mod p,这里的减号是因为a mod p 有逆。于是我们可以枚举 n%T = r1, 然后可以得到n mod p == b*a^(-n) mod p。当n%T = r1确定了,a^(-n) 也就确定了,于是我们又有 n mod p == b*a^(-r) mod p。这样有关于n的两个线性模方程,直接求解即可。

    方法:套中国剩余定理的板子

    code:略

    WA:在统计答案的时候,要小心0对答案的影响

    F. A Game With Numbers

    题意:看题吧。。

    观察:其实一个人状态数很小,只有c(8+5-1, 5-1) = 495,即将八个相同的物品,分到五个不同的箱子的方法数,隔板法计算。所以两个人共同的状态不超过(495-1)*495(-1是因为保证先手手中一定有非0牌),就可以转化成一个有向图上的博弈。处理这种博弈一般的手段就是从结局出发,进行拓扑排序。如果一个状态为LOSE,那么到达它的状态均为WIN。如果一个状态所有后继都为WIN,那么它就是LOSE。剩下的状态都是DEAL。

    方法:可能就是压缩状态麻烦了一点,其实很好写。

    code:

      1 /*
      2  by skydog
      3  */
      4 #include <iostream>
      5 #include <cstdio>
      6 #include <vector>
      7 #include <utility>
      8 #include <algorithm>
      9 #include <cmath>
     10 #include <cstring>
     11 #include <map>
     12 #include <set>
     13 #include <stack>
     14 #include <queue>
     15 #include <deque>
     16 #include <cassert>
     17 
     18 using namespace std;
     19 typedef long long ll;
     20 typedef pair<int, int> ii;
     21 typedef pair<ll, ll> l4;
     22 
     23 #define mp make_pair
     24 #define pb push_back
     25 const int N = 4+1;
     26 const int MAXCARD = 8+1;
     27 const int MAXSTATE = 500;
     28 int id[MAXCARD][MAXCARD][MAXCARD][MAXCARD][MAXCARD];
     29 int state[MAXSTATE][N];
     30 int sz;
     31 int a[N];
     32 int &get_id(int *a)
     33 {
     34     return id[a[0]][a[1]][a[2]][a[3]][a[4]];
     35 }
     36 void dfs(int pos, int left)
     37 {
     38     if (pos == N-1)
     39     {
     40         a[pos] = left;
     41         get_id(a) = ++sz;
     42         for (int i = 0; i < N; ++i)
     43             state[sz][i] = a[i];
     44         return;
     45     }
     46     for (int i = 0; i <= left; ++i)
     47     {
     48         a[pos] = i;
     49         dfs(pos+1, left-i);
     50     }
     51 }
     52 
     53 bool win(int cur)
     54 {
     55     return state[cur][0] == MAXCARD-1;
     56 }
     57 int nxt_state(const int &cur, int prev, int tar)
     58 {
     59     memcpy(a, state[cur], sizeof(a));
     60     assert(a[prev]);
     61     a[prev] -= 1;
     62     a[tar] += 1;
     63     return get_id(a);
     64 }
     65 vector<ii> g[MAXSTATE][MAXSTATE];
     66 int in[MAXSTATE][MAXSTATE];
     67 void build_state()
     68 {
     69     sz = 0;
     70     dfs(0, 8);
     71     cerr << "total state size = " << sz << endl;
     72 }
     73 int ans[MAXSTATE][MAXSTATE];
     74 const int WIN = 1, LOSE = 0, TIE = -1;
     75 void build_graph()
     76 {
     77     for (int i = 1; i <= sz; ++i)
     78         if (!win(i))
     79             for (int j = 1; j <= sz; ++j)
     80                 if (!win(j))
     81                 {
     82                     for (int a = 1; a < N; ++a) if (state[i][a])
     83                         for (int b = 1; b < N; ++b) if (state[j][b])
     84                         {
     85                             int c = (a+b)%N;
     86                             int nxt = nxt_state(i, a, c);
     87                             g[j][nxt].pb(mp(i, j));
     88                             ++in[i][j];
     89                         }
     90                     
     91                 }
     92     queue<ii> q;
     93     memset(ans, TIE, sizeof(ans));
     94     for (int i = 1; i <= sz; ++i)
     95         if (!win(i))
     96             for (int j = 1; j <= sz; ++j)
     97             {
     98                 assert((in[i][j]!=0)^win(j));
     99                 if (!in[i][j])
    100                 {
    101                     ans[i][j] = LOSE;
    102                     q.push(mp(i, j));
    103                 }
    104             }
    105     while (!q.empty())
    106     {
    107         ii cur = q.front();
    108         q.pop();
    109         int cur_ans = ans[cur.first][cur.second];
    110         for (auto pr : g[cur.first][cur.second])
    111         {
    112             int &nxt_ans = ans[pr.first][pr.second];
    113             if (nxt_ans != TIE)
    114                 continue;
    115             if (cur_ans == LOSE)
    116             {
    117                 nxt_ans = WIN;
    118                 q.push(pr);
    119             }
    120             else
    121             {
    122                 int &nxt_in = in[pr.first][pr.second];
    123                 --nxt_in;
    124                 if (nxt_in == 0)
    125                 {
    126                     nxt_ans = LOSE;
    127                     q.push(pr);
    128                 }
    129             }
    130         }
    131     }
    132 }
    133 int read()
    134 {
    135     memset(a, 0, sizeof(a));
    136     for (int i = 1; i < MAXCARD; ++i)
    137     {
    138         int x;
    139         scanf("%d", &x);
    140         ++a[x];
    141     }
    142     return get_id(a);
    143 }
    144 int main()
    145 {
    146     build_state();
    147     build_graph();
    148     int T;
    149     scanf("%d", &T);
    150     for (int kase = 1; kase <= T; ++kase)
    151     {
    152         int f;
    153         scanf("%d", &f);
    154         int a = read(), b = read();
    155         if (f)
    156             swap(a, b);
    157         int ret = ans[a][b];
    158         if (ret == TIE)
    159             puts("Deal");
    160         else
    161             puts(ret^f?"Alice":"Bob");
    162     }
    163 }
    View Code
  • 相关阅读:
    Java NIO系列教程(十二) Java NIO与IO
    Java NIO系列教程(十一) Pipe
    Java NIO系列教程(十) Java NIO DatagramChannel
    Java NIO系列教程(九) ServerSocketChannel
    C#使用cmd运行命令并返回控制台输出信息
    分割nginx日志
    redis启动警告解决
    git worktree 目录修复
    git worktree 稀疏检出(sparseCheckout)
    python json dumps datetime类型报错
  • 原文地址:https://www.cnblogs.com/skyette/p/8424838.html
Copyright © 2011-2022 走看看