• CODE FESTIVAL 2017 qual B 解题报告


    做atcoder总是感到格外的智商不足……感觉atcoder比起codeforces来说题目普遍更有趣,更考验思维orz

    C

    题意:给出无向图,距离为3的点如果未连边,则可以连上一条边,问最多能连多少边。

    解题思路:

    易证距离(可以非简单路)为奇数的均可以连边。

    如果是二分图,则图中不存在奇环,最终状态二分图两部的点彼此有连边。

    非二分图的连通图一定存在奇环,则任意两点若初始距离非奇数,加上奇环之后距离就必可变为奇数。最终状态为完全图。

    按最终状态的边数减去当下边数即可。

      1 #include <cstdio>
      2 #include <iostream>
      3 #include <algorithm>
      4 #include <vector>
      5 #include <set>
      6 #include <map>
      7 #include <string>
      8 #include <cstring>
      9 #include <stack>
     10 #include <queue>
     11 #include <cmath>
     12 #include <ctime>
     13 #include <bitset>
     14 #include <utility>
     15 #include <assert.h>
     16 using namespace std;
     17 #define rank rankk
     18 #define mp make_pair
     19 #define pb push_back
     20 #define xo(a,b) ((b)&1?(a):0)
     21 #define tm tmp
     22 //#pragma comment(linker, "/STACK:1024000000,1024000000") 
     23 //#define LL ll
     24 typedef unsigned long long ull;
     25 typedef pair<int,int> pii;
     26 typedef long long ll;
     27 typedef pair<ll,int> pli;
     28 typedef pair<ll,ll> pll;
     29 const int INF=0x3f3f3f3f;
     30 const ll INFF=0x3f3f3f3f3f3f3f3fll;
     31 const int MAX=1e5+10;
     32 //const ll MAXN=2e8;
     33 //const int MAX_N=MAX;
     34 const ll MOD=998244353;
     35 //const long double pi=acos(-1.0);
     36 //const double eps=0.00000001;
     37 ll gcd(ll a,ll b){return b?gcd(b,a%b):a;}
     38 template<typename T>inline T abs(T a) {return a>0?a:-a;}
     39 template<class T> inline
     40 void read(T& num) {
     41     bool start=false,neg=false;
     42     char c;
     43     num=0;
     44     while((c=getchar())!=EOF) {
     45         if(c=='-') start=neg=true;
     46         else if(c>='0' && c<='9') {
     47             start=true;
     48             num=num*10+c-'0';
     49         } else if(start) break;
     50     }
     51     if(neg) num=-num;
     52 }
     53 inline ll powMM(ll a,ll b,ll M){
     54     ll ret=1;
     55     a%=M;
     56 //    b%=M;
     57     while (b){
     58         if (b&1) ret=ret*a%M;
     59         b>>=1;
     60         a=a*a%M;
     61     }
     62     return ret;
     63 }
     64 void open()
     65 {
     66 //    freopen("1009.in","r",stdin);
     67     freopen("out.txt","w",stdout);
     68 }
     69 int n,m,u,v;
     70 const int maxn=1e5+5;
     71 vector<int> G[maxn];
     72 int color[maxn];
     73 bool bipartite(int u)
     74 {
     75     for(int i=0;i<G[u].size();i++)
     76     {
     77         int v=G[u][i];
     78         if(color[v]==color[u])return false;
     79         if(!color[v])
     80         {
     81             color[v]=3-color[u];
     82             if(!bipartite(v))return false;
     83         }
     84     }
     85     return true;
     86 }
     87 int cnt1;
     88 int main()
     89 {
     90     scanf("%d%d",&n,&m);
     91     for(int i=1;i<=m;i++)
     92     {
     93         scanf("%d%d",&u,&v);G[u].pb(v);G[v].pb(u);
     94     }
     95     color[1]=1;
     96     if(bipartite(1))
     97     {
     98         for(int i=1;i<=n;i++)
     99             if(color[i]==1)++cnt1;
    100         printf("%lld
    ",1LL*(n-cnt1)*cnt1-m);
    101     }
    102     else printf("%lld
    ",1LL*n*(n-1)/2LL-m);
    103     return 0;
    104 }
    View Code

    D

    题意:给出01字符串,每次操作将101变为010,问最多做多少次操作。

    解题思路:

    注意到只有 若干个1+0+若干个1 的形式才能进行操作。

    且实际上每次只有 x个1+0+1   1+0+x个1这部分会操作  像11011 实际上操作只能选择最初的4个数,或末尾的4个数 因为101操作后1的周围就被0包围,进行2次之后就与另一部分的1隔开了2个0,无法与之继续操作。

    故考虑dp,只需要对每个 x个1+0+1 和1+0+x个1的dp即可。

    x个1+0+1的操作次数为x。

      1 #include <cstdio>
      2 #include <iostream>
      3 #include <algorithm>
      4 #include <vector>
      5 #include <set>
      6 #include <map>
      7 #include <string>
      8 #include <cstring>
      9 #include <stack>
     10 #include <queue>
     11 #include <cmath>
     12 #include <ctime>
     13 #include <bitset>
     14 #include <utility>
     15 #include <assert.h>
     16 using namespace std;
     17 #define rank rankk
     18 #define mp make_pair
     19 #define pb push_back
     20 #define xo(a,b) ((b)&1?(a):0)
     21 #define tm tmp
     22 //#pragma comment(linker, "/STACK:1024000000,1024000000") 
     23 //#define LL ll
     24 typedef unsigned long long ull;
     25 typedef pair<int,int> pii;
     26 typedef long long ll;
     27 typedef pair<ll,int> pli;
     28 typedef pair<ll,ll> pll;
     29 const int INF=0x3f3f3f3f;
     30 const ll INFF=0x3f3f3f3f3f3f3f3fll;
     31 const int MAX=5e5+10;
     32 //const ll MAXN=2e8;
     33 //const int MAX_N=MAX;
     34 const ll MOD=10007;
     35 //const long double pi=acos(-1.0);
     36 //const double eps=0.00000001;
     37 ll gcd(ll a,ll b){return b?gcd(b,a%b):a;}
     38 template<typename T>inline T abs(T a) {return a>0?a:-a;}
     39 template<class T> inline
     40 void read(T& num) {
     41     bool start=false,neg=false;
     42     char c;
     43     num=0;
     44     while((c=getchar())!=EOF) {
     45         if(c=='-') start=neg=true;
     46         else if(c>='0' && c<='9') {
     47             start=true;
     48             num=num*10+c-'0';
     49         } else if(start) break;
     50     }
     51     if(neg) num=-num;
     52 }
     53 inline ll powMM(ll a,ll b,ll M){
     54     ll ret=1;
     55     a%=M;
     56 //    b%=M;
     57     while (b){
     58         if (b&1) ret=ret*a%M;
     59         b>>=1;
     60         a=a*a%M;
     61     }
     62     return ret;
     63 }
     64 void open()
     65 {
     66 //    freopen("1009.in","r",stdin);
     67     freopen("out.txt","w",stdout);
     68 }
     69  
     70 int n;
     71 char a[MAX];
     72 int num[MAX],dp[MAX];
     73 int an,tem;
     74 int main()
     75 {
     76     scanf("%d",&n);
     77     scanf("%s",a+1);
     78     for(int i=1;i<=n;i++)
     79     {
     80         if(a[i]=='1')
     81             num[i]=num[i-1]+1;
     82     }
     83     for(int i=n-1;i>=1;i--)
     84         if(a[i]=='1')
     85             num[i]=max(num[i],num[i+1]);
     86     for(int i=2;i<=n-1;i++)
     87     {
     88         if(a[i]=='0'&&a[i-1]=='1'&&a[i+1]=='1')
     89         {
     90             for(int j=1;j<=num[i+1];j++)
     91                 dp[i+j]=max(dp[i-2]+j,dp[i+j]);
     92             for(int j=1;j<=num[i-1];j++)
     93                 dp[i+1]=max(dp[i+1],dp[i-j-1]+j);
     94         }
     95         dp[i]=max(dp[i],dp[i-1]);
     96         an=max(an,dp[i]);
     97     }
     98     an=max(an,dp[n]);
     99     an=max(an,dp[n+1]);
    100  
    101     printf("%d
    ",an);
    102 }
    View Code

    E

    题意:A个红球,B个蓝球,按前A个是红,后B个是蓝摆成一行。任选s 两个位置,每次取出该行行首或s位置或t位置的球。所有的蓝、红球认为是一样的,问有多少种不同的取法。(两种取法认为是不同的,当且仅当存在某次取出,取出的球颜色不同)

    以下代码是完全依照官方题解写的。

    从(A,B)走到与第一个三角形的交点的距离是固定的(因为三角形边界的斜率为-1)方案数只与纵坐标之差有关。

    同理到与第二个三角形的交点的方案数也只与纵坐标之差有关。下面考虑两个三角形位置和大小的选择。均为等腰直角三角形,设其直角边长度分别为x,y,则x>=s,y>=t,x+y<=A,取法个数为C(a-s-t+2,2)

    (对于a个位置取出s+t个,加上边界的2个,选出2个位置,之后再加上s 保证满足前面的限制条件,总方法即为此)

    枚举s 即可。

     1 #include <cstdio>
     2 #include <iostream>
     3 #include <algorithm>
     4 #include <vector>
     5 #include <set>
     6 #include <map>
     7 #include <string>
     8 #include <cstring>
     9 #include <stack>
    10 #include <queue>
    11 #include <cmath>
    12 #include <ctime>
    13 #include <bitset>
    14 #include <utility>
    15 #include <assert.h>
    16 using namespace std;
    17 #define rank rankk
    18 #define mp make_pair
    19 #define pb push_back
    20 #define xo(a,b) ((b)&1?(a):0)
    21 #define tm tmp
    22 //#pragma comment(linker, "/STACK:1024000000,1024000000") 
    23 //#define LL ll
    24 typedef unsigned long long ull;
    25 typedef pair<int,int> pii;
    26 typedef long long ll;
    27 typedef pair<ll,int> pli;
    28 typedef pair<ll,ll> pll;
    29 const int INF=0x3f3f3f3f;
    30 const ll INFF=0x3f3f3f3f3f3f3f3fll;
    31 const int MAX=5e5+10;
    32 //const ll MAXN=2e8;
    33 //const int MAX_N=MAX;
    34 const ll MOD=1e9+7;
    35 //const long double pi=acos(-1.0);
    36 //const double eps=0.00000001;
    37 ll gcd(ll a,ll b){return b?gcd(b,a%b):a;}
    38 template<typename T>inline T abs(T a) {return a>0?a:-a;}
    39 template<class T> inline
    40 void read(T& num) {
    41     bool start=false,neg=false;
    42     char c;
    43     num=0;
    44     while((c=getchar())!=EOF) {
    45         if(c=='-') start=neg=true;
    46         else if(c>='0' && c<='9') {
    47             start=true;
    48             num=num*10+c-'0';
    49         } else if(start) break;
    50     }
    51     if(neg) num=-num;
    52 }
    53 inline ll powMM(ll a,ll b,ll M){
    54     ll ret=1;
    55     a%=M;
    56 //    b%=M;
    57     while (b){
    58         if (b&1) ret=ret*a%M;
    59         b>>=1;
    60         a=a*a%M;
    61     }
    62     return ret;
    63 }
    64 void open()
    65 {
    66 //    freopen("1009.in","r",stdin);
    67     freopen("out.txt","w",stdout);
    68 }
    69  
    70 const int N = 2020;
    71 ll C[N][N];
    72 void init() {
    73         for (int i = 0; i < N; i ++) C[i][0] = C[i][i] = 1;
    74         for (int i = 1; i < N; i ++) {
    75                 for (int j = 1; j < i; j ++) {
    76                         C[i][j] = (C[i - 1][j] + C[i - 1][j - 1]) % MOD;
    77                 }
    78         }
    79 }
    80 int a,b;
    81 ll an,lin;
    82 int main()
    83 {
    84     init();
    85     scanf("%d%d",&a,&b);
    86     an=a+1;
    87     for(int i=1;i<=min(a,b-1);i++)//第一次向下的位置的横坐标
    88     {
    89         for(int j=0;j<i&&j+i<=a;j++)
    90         {
    91             lin=C[b-1][i]*C[i-1][j]%MOD*C[a-i-j+2][2]%MOD;
    92             an=(an+lin)%MOD;
    93         }
    94     }
    95     printf("%lld
    ",an);
    96  
    97 }
    View Code

    F

    如果一个环由2部分构成(长度不一定相同,但同一部分的位置不能改变,且每一部分的任意前缀串s,其任意长度的后缀均比相同长度的前缀字典序”不小于”)设两部分分别为xy

    将其连接而成的一个环,只可能由这两部分的起始位置作为起点的串可能为Smallest Cyclic Shift(以下简写为SCS)因为取某部分的后缀作为开头,则其已经不小于该部分的前缀,如果是大于显然取前缀作为开头更优,如果是等于,最后比较的还是两部分的前缀。

    而x、y比较得x字典序更小,故xy即为所求的字符串。

    一般地,如果一个环由k部分构成(k>=3),易证在欲使最终的SCS最大的情况下,将k部分转化成k-1部分,一定是选择字典序最小的部分与字典序最大的部分相连。

    最初有x+y+z个部分,分别是x个a,y个b,z个c,将其按上述操作反复进行即可。

     1  #include <cstdio>
     2 #include <iostream>
     3 #include <algorithm>
     4 #include <vector>
     5 #include <set>
     6 #include <map>
     7 #include <string>
     8 #include <cstring>
     9 #include <stack>
    10 #include <queue>
    11 #include <cmath>
    12 #include <ctime>
    13 #include <bitset>
    14 #include <utility>
    15 #include <assert.h>
    16 using namespace std;
    17 #define rank rankk
    18 #define mp make_pair
    19 #define pb push_back
    20 #define xo(a,b) ((b)&1?(a):0)
    21 #define tm tmp
    22 //#pragma comment(linker, "/STACK:1024000000,1024000000") 
    23 //#define LL ll
    24 typedef unsigned long long ull;
    25 typedef pair<int,int> pii;
    26 typedef long long ll;
    27 typedef pair<ll,int> pli;
    28 typedef pair<ll,ll> pll;
    29 const int INF=0x3f3f3f3f;
    30 const ll INFF=0x3f3f3f3f3f3f3f3fll;
    31 const int MAX=5e5+10;
    32 //const ll MAXN=2e8;
    33 //const int MAX_N=MAX;
    34 const ll MOD=1e9+7;
    35 //const long double pi=acos(-1.0);
    36 //const double eps=0.00000001;
    37 ll gcd(ll a,ll b){return b?gcd(b,a%b):a;}
    38 template<typename T>inline T abs(T a) {return a>0?a:-a;}
    39 template<class T> inline
    40 void read(T& num) {
    41     bool start=false,neg=false;
    42     char c;
    43     num=0;
    44     while((c=getchar())!=EOF) {
    45         if(c=='-') start=neg=true;
    46         else if(c>='0' && c<='9') {
    47             start=true;
    48             num=num*10+c-'0';
    49         } else if(start) break;
    50     }
    51     if(neg) num=-num;
    52 }
    53 inline ll powMM(ll a,ll b,ll M){
    54     ll ret=1;
    55     a%=M;
    56 //    b%=M;
    57     while (b){
    58         if (b&1) ret=ret*a%M;
    59         b>>=1;
    60         a=a*a%M;
    61     }
    62     return ret;
    63 }
    64 void open()
    65 {
    66 //    freopen("1009.in","r",stdin);
    67     freopen("out.txt","w",stdout);
    68 }
    69 int x,y,z;
    70 vector<string>s;
    71 int main()
    72 {
    73     scanf("%d%d%d",&x,&y,&z);
    74     for(int i=0;i<x;i++)s.pb("a");
    75     for(int i=0;i<y;i++)s.pb("b");
    76     for(int j=0;j<z;j++)s.pb("c");
    77     while(s.size()>1)
    78     {
    79         sort(s.begin(),s.end());
    80         s[0]+=s[s.size()-1];
    81         s.pop_back();
    82     }
    83     cout<<s[0]<<"
    ";
    84 }
    85 /*
    86 8
    87 11011011
    88 */
    View Code
  • 相关阅读:
    css兼容
    CSS 后代选择器
    解决ul里最后一个li的margin问题
    亿级数据库分片分库架构设计亿
    sem
    百度竞价匹配模式
    sql之left join、right join、inner join的区别
    .NET跨平台实践:再谈用C#开发Linux守护进程 — 完整篇
    .NET跨平台实践:用C#开发Linux守护进程
    php执行外部命令函数:exec()、passthru()、system()、shell_exec()对比
  • 原文地址:https://www.cnblogs.com/quintessence/p/7648547.html
Copyright © 2020-2023  润新知