zoukankan      html  css  js  c++  java
  • 2014/3/9 长沙多校(第二次)

    A: 二分图着色/图中有奇圈

    分析:难在思路上,如果对图论的算法掌握比较全面的话,看到这么大的n和multiply,应该想到o(n)的图搜索;

    这道题应该判连通,但是数据很水,不判也过。二分图不能拿来判连通。

    题源:http://acm.hdu.edu.cn/showproblem.php?pid=3478

    代码:

     1 #include <iostream>
     2 #include <string.h>
     3 #include <vector>
     4 #include <queue>
     5 #include <stdio.h>
     6 #define maxn 100000+5
     7 using namespace std;
     8 vector<int> G[maxn];
     9 int T,n,m,s;
    10 bool mark[maxn];
    11 int color[maxn];
    12 int nextint(){int x;scanf("%d",&x);return x;}
    13 void read()
    14 {
    15     n=nextint();m=nextint();s=nextint();
    16     for(int i=0;i<=n;i++)
    17     G[i].clear();
    18     for(int i=1;i<=m;i++)
    19     {
    20         int u,v;
    21         u=nextint();
    22         v=nextint();
    23         G[u].push_back(v);
    24         G[v].push_back(u);
    25     }
    26     return ;
    27 }
    28 bool BFS(int st)
    29 {
    30     bool odd=false;
    31     int cnt=0;
    32     queue<int> Q;
    33     Q.push(st);
    34     while(!Q.empty())
    35     {
    36         int k=Q.front();Q.pop();
    37         if (mark[k]) continue;
    38         cnt++;
    39         mark[k]=true;
    40         for(int i=0;i<G[k].size();i++)
    41         {
    42             int v=G[k][i];
    43             if (mark[v] && color[k]==color[v]) odd=true;
    44             color[v]=1-color[k];
    45             Q.push(v);
    46         }
    47     }
    48     if (odd && cnt==n) return true;else return false;
    49 }
    50 bool isok()
    51 {
    52     if (n==1) return true;
    53     memset(mark,0,sizeof(mark));
    54     memset(color,0,sizeof(color));
    55     return BFS(s);
    56 //    return DFS(0);
    57 }
    58 int main()
    59 {
    60     cin>>T;
    61     for(int cas=1;cas<=T;cas++){
    62         read();
    63         if (isok())
    64         printf("Case %d: YES
    ",cas);
    65         else printf("Case %d: NO
    ",cas);
    66     }
    67     return 0;
    68 }
    View Code

    E:排列组合

    分析:写在代码中,注意坑:开long long,m==2的时候

    题源:http://acm.hdu.edu.cn/showproblem.php?pid=3482

    代码:

     1 /*
     2 分类讨论:
     3 N<M  M^N
     4 N=M  M+A(M,M)
     5 N>M  M+A(M,M)
     6 要注意:M==2时,ans=N^2
     7         M==1
     8         开long long
     9 */
    10 #include <iostream>
    11 #include <string.h>
    12 #include <stdio.h>
    13 #define Mod 987654321
    14 
    15 using namespace std;
    16 int n,m;
    17 int main()
    18 {
    19     while(cin>>n>>m && n>0 && m>0)
    20     {
    21         long long  ans=0;
    22         if (m==1) {
    23             ans=1;
    24         }
    25         else if (m==2) {
    26             long long t=1;
    27             for(int i=1;i<=n;i++) t=(t*2)%Mod;
    28             ans=t;
    29         }
    30         else
    31         {
    32             if (n>=m){
    33                 long long t=1;
    34                 for(int i=1;i<=m;i++) t=(t*i)%Mod;
    35                 ans=(m+t)%Mod;
    36             }
    37             else{
    38                 long long t=1;
    39                 for(int i=1;i<=n;i++) t=(t*m)%Mod;
    40                 ans=t;
    41             }
    42         }
    43         cout<<ans<<endl;
    44     }
    45     return 0;
    46 }
    View Code

    G:枚举+模拟

    分析:别忘了枚举这个有效手段,矩阵写在结构体中,更容易编码;网上有些只统计每行1的个数,判断相等或互补的方法是错的。

    下面给组数据:

    2 5
    1 1 0 0 0
    1 0 1 0 0

    1 0 1 0 0
    0 1 0 1 1

    答案是No

    题源:http://acm.hdu.edu.cn/showproblem.php?pid=3484

    代码:

     1 #include<iostream>
     2 #include<string.h>
     3 #include<stdio.h>
     4 #include<vector>
     5 #define maxn 105
     6 using namespace std;
     7 
     8 int n,m;
     9 
    10 int nextint(){int x;scanf("%d",&x);return x;}
    11 
    12 struct Matrix
    13 {
    14     int n,m;
    15     int mat[maxn][maxn];
    16     bool mark[maxn];
    17     void init(int n,int m)
    18     {
    19         this->n=n;
    20         this->m=m;
    21     }
    22     void print()
    23     {
    24         for(int i=1;i<=n;i++)
    25         {
    26             for(int j=1;j<=m;j++) cout<<mat[i][j]<<" ";
    27             cout<<endl;
    28         }
    29     }
    30     void read()
    31     {
    32         for(int i=1;i<=n;i++)
    33         for(int j=1;j<=m;j++)
    34         mat[i][j]=nextint();
    35     }
    36     void SwapColumn(int c1,int c2)
    37     {
    38         for(int i=1;i<=n;i++)
    39         swap(mat[i][c1],mat[i][c2]);
    40     }
    41     void ChangeRow(Matrix M)
    42     {
    43         for(int i=1;i<=n;i++){
    44             if (mat[i][1]!=M.mat[i][1])
    45               for(int j=1;j<=m;j++) mat[i][j]=mat[i][j]^1;
    46         }
    47     }
    48     bool check(Matrix M)
    49     {
    50         memset(mark,0,sizeof(mark));
    51         for(int i=1;i<=m;i++)
    52         {
    53             bool ok=false;
    54             for(int j=1;j<=m;j++)
    55             {
    56                 int cnt=0;
    57                 if (mark[j]) continue;
    58                 for(int l=1;l<=n;l++)
    59                     if (M.mat[l][i]!=mat[l][j]) cnt++;
    60                 if (!cnt) ok=true;
    61             }
    62             if (!ok) return false;
    63         }
    64         return true;
    65     }
    66 }M1,M2;
    67 
    68 int main()
    69 {
    70     while(cin>>n>>m && n>0 && m>0)
    71     {
    72         bool ans=false;
    73         M1.init(n,m);M2.init(n,m);
    74         M1.read();M2.read();
    75         for(int i=1;i<=m;i++)
    76         {
    77             M1.SwapColumn(1,i);
    78             M1.ChangeRow(M2);
    79 //            M1.print();
    80             if (M1.check(M2)) {
    81                 ans=true; break;
    82             }
    83         }
    84         if (ans) cout<<"Yes"<<endl;else cout<<"No"<<endl;
    85     }
    86     return 0;
    87 }
    View Code

    H:dp

    分析:dp[i][0],dp[i][1]:分别表示长度为i,以0,1结尾的串...

             注意 dp[i][1]=dp[i-1][0]+dp[i-1][1]-以10结尾的个数(dp[i-1][0]-dp[i-2][1])即可,边界写到dp[2]

    题源:http://acm.hdu.edu.cn/showproblem.php?pid=3485

    代码:

     1 #include <iostream>
     2 #include <string.h>
     3 #include <stdio.h>
     4 #include <cmath>
     5 #define maxn 10005
     6 
     7 using namespace std;
     8 
     9 int n;
    10 int dp[maxn][2];
    11 
    12 void init()
    13 {
    14     dp[0][0]=0;dp[0][1]=0;
    15     dp[1][0]=1;dp[1][1]=1;
    16     dp[2][0]=2;dp[2][1]=2;
    17     for(int i=3;i<maxn;i++)
    18     {
    19         dp[i][0]=dp[i-1][1]+dp[i-1][0];
    20         dp[i][0]%=9997;
    21         dp[i][1]=dp[i-1][1]+dp[i-2][0];
    22         dp[i][1]%=9997;
    23     }
    24     return;
    25 }
    26 int main()
    27 {
    28     init();
    29     while(cin>>n && n>=0)
    30     {
    31         printf("%d
    ",(dp[n][0]+dp[n][1])%9997);
    32     }
    33     return 0;
    34 }
    View Code

    I:RMQ

    分析:1m的时限太小了,需要优化(读入、记录搜索量)才能过,而且这道题也较有歧义,开始枚举每组的人数做,就一直W。

    吐槽一下自己,这么经典的算法都不知道,明显在大白书上现成的模板啊。

    题源:http://acm.hdu.edu.cn/showproblem.php?pid=3486

    代码:

     1 /*I题:
     2 经典的RMQ算法,在白书的198页;
     3 d[i][j]指从i位置开头,长度为2^j的数字中最大/最小的数是多少
     4 j上限是lg2(R)*/
     5 #include <iostream>
     6 #include <string.h>
     7 #include <vector>
     8 #include <stdio.h>
     9 #include <stdlib.h>
    10 #define maxn 200000+5
    11 #define LL long long
    12 using namespace std;
    13 int d[maxn][20];
    14 int A[maxn],n;
    15 LL tar,ans;
    16 
    17 void read(int &d)
    18 {
    19     char ch;
    20     while(ch=getchar(),ch<48||ch>57); d=ch-48;
    21     while(ch=getchar(),ch<58&&ch>47) d=d*10+ch-48;
    22 }
    23 
    24 void RMQ_init(){
    25     memset(d,0,sizeof(d));
    26     for(int i=0;i<n;i++) d[i][0]=A[i];
    27     for(int j=1;(1<<j)<=n;j++)
    28       for(int i=0;i+(1<<j)-1<n;i++)
    29         d[i][j]=max(d[i][j-1],d[i+(1<<(j-1))][j-1]);
    30 }
    31 
    32 LL RMQ(int L,int R)
    33 {
    34     int k=0;
    35     while((1<<(k+1))<=R-L+1) k++;
    36     return max(d[L][k],d[R-(1<<k)+1][k]);
    37 }
    38 
    39 int main()
    40 {
    41     while(cin>>n>>tar && n>=0)
    42     {
    43         for(int i=0;i<n;i++) {
    44             read(A[i]);
    45         }
    46         RMQ_init();
    47         LL tot=0;int p_num=-1;ans=-1;
    48         for(int i=1;i<=n;i++)//枚举组数
    49         {
    50             if (i*1000<=tar) continue;
    51             int num=n/i,st=1;
    52             if (p_num!=num) {//优化,记录上一次结果,可能组数改变,每组人数不变
    53                 tot=0;st=1;
    54             }else st=num*(i-1)+1;
    55             for(int j=st;j+num-1<=num*i;j+=num)//j是每组的开头位置
    56             {
    57                 int  L=j,R=j+num-1;
    58                 L--,R--;
    59                 tot+=RMQ(L,R);//查询从0位开始
    60             }
    61             p_num=num;
    62             if (tot>tar){
    63                 ans=i;break;
    64             }
    65         }
    66         printf("%d
    ",ans);
    67     }
    68     return 0;
    69 }
    View Code
  • 相关阅读:
    setState 是异步吗?
    React优化点滴
    JS原型,作用域,this,闭包
    Webpack 模块化打包优化
    JS异步编程
    Web网络安全
    Http2.0和Http3.0
    Http协议基础
    Harris算子以及未来的规划...
    剑指offer 二维数组查找
  • 原文地址:https://www.cnblogs.com/little-w/p/3590684.html
Copyright © 2011-2022 走看看