zoukankan      html  css  js  c++  java
  • 2017-10-23学大伟业Day1

    T1 叉叉

    题目名称

    叉叉

    程序文件名

    cross

    输入文件名

    cross.in

    输出文件名

    cross.out

    每个测试点时限

    1秒

    内存限制

    128MB

    测试点数目

    10

    每个测试点分值

    10

    是否有部分分

    试题类型

    传统

    题目描述

    现在有一个字符串,每个字母出现的次数均为偶数。接下来我们把第一次出现的字母a和第二次出现的a连一条线,第三次出现的和四次出现的字母a连一条线,第五次出现的和六次出现的字母a连一条线...对其他25个字母也做同样的操作。

    现在我们想知道有多少对连线交叉。交叉的定义为一个连线的端点在另外一个连线的内部,另外一个端点在外部。

    下图是一个例子,共有三对连线交叉(我们连线的时候,只能从字符串上方经过)。

    输入格式

    一行一个字符串。保证字符串均由小写字母组成,且每个字母出现次数为偶数次。

    输出格式

    一个整数,表示答案。

    样例输入

    abaazooabz

    样例输出

    3

    数据范围

    对于30% 的数据,字符串长度不超过50。

    对于100% 的数据,字符串长度不超过100,000。

    处理出每对字符的两个位置,按左端点排序,判断是否会相交,加一个小剪枝、、、暴力做法数据水就过了。。

     1 #include <algorithm>
     2 #include <cstring>
     3 #include <cstdio>
     4 
     5 const int N(100005);
     6 int cnt,n,ans;
     7 struct Node {
     8     int l,r;
     9     bool operator < (const Node&x)const
    10     {
    11         return l<x.l;
    12     }
    13 }a[N];
    14 char s[N];
    15 
    16 int Presist()
    17 {
    18     freopen("cross.in","r",stdin);
    19     freopen("cross.out","w",stdout);
    20     scanf("%s",s+1); n=strlen(s+1);
    21     cnt=1;
    22     for(int k=0; k<26; ++k)
    23       for(int i=1; i<=n; ++i)
    24           if(s[i]-'a'==k)
    25           {
    26               if(a[cnt].r) a[++cnt].l=i;
    27               else if(!a[cnt].l) a[cnt].l=i;
    28                    else a[cnt].r=i;
    29         }
    30     std::sort(a+1,a+cnt+1);
    31     for(int i=1; i<=cnt; ++i)
    32 //        printf("%d %d
    ",a[i].l,a[i].r);
    33       for(int j=i+1; j<=cnt; ++j)
    34       {
    35           if(a[i].r<a[j].l) break;
    36           ans+=(a[i].r<a[j].r);
    37       }
    38     printf("%d
    ",ans);
    39     return 0;
    40 }
    41 
    42 int Aptal=Presist();
    43 int main(int argc,char**argv){;}
    AC

    T2 跳跳虎想回家

    k==0的就是普通的最短路,k==1的可以Floyd求出多源最短路,枚举每个传送通道更新最小值,

    另外就是乱搞的(把传送通道全加进去跑最短路。。可能还是数据水)、、考试时数组开小了80分、

      1 #include <cstdio>
      2 #include <queue>
      3 
      4 #define min(a,b) ((a)<(b)?(a):(b))
      5 
      6 inline void read(int &x)
      7 {
      8     x=0; register char ch=getchar();
      9     for(; ch>'9'||ch<'0'; ) ch=getchar();
     10     for(; ch>='0'&&ch<='9'; ch=getchar()) x=x*10+ch-'0';
     11 }
     12 
     13 const int INF(0x3f3f3f);
     14 const int M(2333);
     15 const int N(505);
     16 int n,m,q,k,ans;
     17 int dis[N][N];
     18 bool vis[N];
     19 
     20 int head[N],sumedge;
     21 struct Edge {
     22     int v,next,w;
     23     Edge(int v=0,int next=0,int w=0):
     24         v(v),next(next),w(w){}
     25 }edge[M<<1];
     26 inline void ins(int u,int v,int w)
     27 {
     28     edge[++sumedge]=Edge(v,head[u],w);
     29     head[u]=sumedge; dis[u][v]=w;
     30 }
     31 
     32 struct Node {
     33     int pos,dis;
     34     bool operator < (const Node&x)const
     35     {
     36         return dis>x.dis;
     37     }
     38 }u,v;
     39 std::priority_queue<Node>que;
     40 
     41 inline void Dijkstra(int s)
     42 {
     43     for(int i=1; i<=n; ++i)
     44         dis[s][i]=INF,vis[i]=0;
     45     u.dis=dis[s][s]=0,u.pos=s;
     46     for(; !que.empty(); ) que.pop(); que.push(u);
     47     for(; !que.empty(); )
     48     {
     49         u=que.top(); que.pop();
     50         if(vis[u.pos]) continue; vis[u.pos]=1;
     51         for(int i=head[u.pos]; i; i=edge[i].next)
     52         {
     53             v.pos=edge[i].v;
     54             if(dis[s][v.pos]>dis[s][u.pos]+edge[i].w)
     55             {
     56                 dis[s][v.pos]=dis[s][u.pos]+edge[i].w;
     57                 v.dis=dis[s][v.pos]; que.push(v);
     58             }
     59         }
     60     }
     61 }
     62 
     63 struct Road {
     64     int u,v,w;
     65     Road(int u=0,int v=0,int w=0):u(u),v(v),w(w){}
     66 }road[M];
     67 
     68 inline void violence()
     69 {
     70     for(int k=1; k<=n; ++k)
     71       for(int i=1; i<=n; ++i)
     72           for(int j=1; j<=n; ++j)
     73           dis[i][j]=min(dis[i][j],dis[i][k]+dis[k][j]);
     74     ans=dis[1][n];
     75     for(int u,w,v,i=1; i<=q; ++i)
     76     {
     77         u=road[i].u,v=road[i].v,w=road[i].w;
     78         ans=min(ans,dis[1][u]+dis[v][n]+w);
     79     }
     80     printf("%d
    ",ans>=INF?(-1):ans);
     81 }
     82 
     83 inline void violence2()
     84 {
     85     for(int u,w,v,i=1; i<=q; ++i)
     86         ins(road[i].u,road[i].v,road[i].w);
     87     Dijkstra(1); printf("%d
    ",dis[1][n]>=INF?(-1):dis[1][n]);
     88 }
     89 
     90 int Presist()
     91 {
     92     freopen("move.in","r",stdin);
     93     freopen("move.out","w",stdout);
     94     read(n),read(m),read(q),read(k);
     95     for(int i=1; i<=n; ++i)
     96       for(int j=1; j<=n; ++j)
     97           dis[i][j]=(i!=j)*INF;
     98     for(int u,v,w,i=1; i<=m; ++i)
     99         read(u),read(v),read(w),ins(u,v,w);
    100     for(int u,v,w,i=1; i<=q; ++i)
    101         read(u),read(v),read(w),road[i]=Road(u,v,w);
    102     if(!k) { Dijkstra(1); printf("%d
    ",dis[1][n]>=INF?(-1):dis[1][n]); return 0;}
    103     else if(k==1) { violence(); return 0; }
    104          else { violence2(); return 0; }
    105     return 0;
    106 }
    107 
    108 int Aptal=Presist();
    109 int main(int argc,char**argv){;}
    AC

    T3 秀秀 和哺 噜国 ( cut )

    f[i][j]表示以i为根,连通块大小为k的满足题目要求联通个数的方案数,f[i][0]表示以i为根的所有合法方案数

    对于u的一个孩子v,f[u][j+k]+=f[u][j]*f[v][k],(乘法原理,一颗以u的孩子为根的树的贡献与其余树互不影响)

    f[u][0]+=f[u][i](k<=i<=size[u])

    只枚举当前 u 所在子树的大小,每当枚举到它的其中孩子时,当前 u 所在子树的大小加上它孩子为根的子树的大小。

    可以理解为每一个点对只被枚举到一次。 这样可以优化到n^2

    ans=f[root][0]

     1 #include <cstdio>
     2 
     3 #define min(a,b) ((a)<(b)?(a):(b))
     4 
     5 inline void read(int &x)
     6 {
     7     x=0; register char ch=getchar();
     8     for(; ch>'9'||ch<'0'; ) ch=getchar();
     9     for(; ch>='0'&&ch<='9'; ch=getchar()) x=x*10+ch-'0';
    10 }
    11 const int mod(786433);
    12 const int N(5233);
    13 int n,q,ans,dis[N][N];
    14 int head[N],sumedge;
    15 struct Edge {
    16     int v,next;
    17     Edge(int v=0,int next=0):v(v),next(next){}
    18 }edge[N<<1];
    19 inline void ins(int u,int v)
    20 {
    21     edge[++sumedge]=Edge(v,head[u]);
    22     head[u]=sumedge,dis[u][v]=1;
    23 }
    24 
    25 int size[N],tmp[N],f[N][N];
    26 void DFS(int u,int pre)
    27 {
    28     size[u]=1; f[u][1]=1;
    29     for(int v,i=head[u]; i; i=edge[i].next)
    30     {
    31         v=edge[i].v; if(v==pre) continue;
    32         DFS(v,u); int tot=size[u]+size[v];
    33         for(int j=1; j<=tot; ++j) tmp[j]=0;
    34         for(int j=1; j<=size[u]; ++j)
    35             tmp[j]=1ll*f[v][0]*f[u][j]%mod;
    36         for(int j=1; j<=size[u]; ++j)
    37           for(int k=1; k<=size[v]; ++k)
    38               tmp[k+j]=(tmp[k+j]%mod+1ll*f[u][j]*f[v][k]%mod)%mod;
    39         for(int j=1; j<=tot; ++j) f[u][j]=tmp[j];
    40         size[u]+=size[v];
    41     }
    42     for(int i=q; i<=size[u]; ++i) f[u][0]=(f[u][0]+f[u][i])%mod;
    43 }
    44 
    45 int Presist()
    46 {
    47 //    freopen("cut.in","r",stdin);
    48 //    freopen("cut.out","w",stdout);
    49     read(n),read(q);
    50     for(int i=1; i<=n; ++i)
    51       for(int j=1; j<=n; ++j)
    52         dis[i][j]=(i!=j)*(n+1);
    53     for(int u,v,i=1; i<n; ++i)
    54         read(u),read(v),ins(u,v);
    55     DFS(1,-1);
    56     printf("%d
    ",f[1][0]);
    57     return 0;
    58 }
    59 
    60 int Aptal=Presist();
    61 int main(int argc,char**argv){;}
    AC
    ——每当你想要放弃的时候,就想想是为了什么才一路坚持到现在。
  • 相关阅读:
    CentOS7安装MySQL5.7
    .gdbinit文件配置
    Linux 动态库加载
    GDB常用调试命令(二)
    git删除缓存区中文件
    git添加空文件夹
    Linux 打开core dump功能
    C++ 预处理器
    C++ 模板
    C++ 命名空间
  • 原文地址:https://www.cnblogs.com/Shy-key/p/7716544.html
Copyright © 2011-2022 走看看