zoukankan      html  css  js  c++  java
  • 【寒假集训系列DAY.1】

    Problem A. String Master(master.c/cpp/pas)

    题目描述

     所谓最长公共子串,比如串 A:“abcde”,串 B:“jcdkl”,则它们的最长公共子串为串 “cd”,即长
    度最长的字符串,且在两个串中都作为连续子串出现过。
    给定两个长度都为 n 的字符串,对于字符串大师的你来说,求它们的最长公共子串再简单不过了。
    所以现在你有 k 次修改机会,每次你可以选择其中某个串的某个位置,将其修改成任意字符。
    你需要合理使用这 k 次修改机会,使得修改之后两个串的最长公共子串最长。相信对于字符串大师
    的你来说,这个问题也难不倒你。
    Input
    第一行包含两个整数 n, k,分别表示字符串的长度和修改次数。
    第二行包含一个长度为 n 的仅由小写字符构成的字符串 S。
    第三行包含一个长度为 n 的仅由小写字符构成的字符串 T。
    Output
    输出一行一个整数,即修改完毕之后两个串的最长公共子串的长度。

    k<=n<=300

    题目大意:两个字符串,任意改动k个字母,使得最长公共子串最长

    思路:两个指针i,j,代表从S串第i个位置开始,T串从第j个位置开始,枚举长度len,求出在两边找出的子串在k次修改机会内的最大长度

    复杂度:O(N^3)

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<algorithm>
     5 using namespace std;
     6 inline int read(){
     7     char chr=getchar();    int f=1,ans=0;
     8     while(!isdigit(chr)) {if(chr=='-') f=-1;chr=getchar();}
     9     while(isdigit(chr))  {ans=(ans<<3)+(ans<<1);ans+=chr-'0';chr=getchar();}
    10     return ans*f;
    11 }
    12 void write(int x){
    13     if(x<0) putchar('-'),x=-x;
    14     if(x>9) write(x/10);
    15     putchar(x%10+'0');
    16 }
    17 const int N=301;
    18 char S[N],T[N],tS[N],tT[N];
    19 int n,k,f[N][N];
    20 inline int Check(char *S,char *T){
    21     int ans=0;
    22     for(int i=1;i<=n;i++)
    23         for(int j=1;j<=n;j++){
    24             int cs=0,len;
    25             for(len=1;len<=min(n-i+1,n-j+1);len++){
    26                 if(S[i+len-1]!=T[j+len-1]) 
    27                     if(cs>=k) break;
    28                     else cs++;
    29             }ans=max(ans,len-1);
    30         }return ans;
    31     
    32 }
    33 int main(){
    34     freopen("master.in","r",stdin);
    35     freopen("master.out","w",stdout);
    36     n=read(),k=read();
    37     scanf("%s",S+1);scanf("%s",T+1);
    38     write(Check(S,T));
    39     return 0;
    40 }

    Problem B. Tourist Attractions(tour.c/cpp/pas)

    题目描述

     在美丽的比特镇一共有 n 个景区,编号依次为 1 到 n,它们之间通过若干条双向道路连接。
    Byteasar 慕名来到了比特镇旅游,不过由于昂贵的门票费,他只能负担起 4 个景区的门票费。他可
    以在任意景区开始游览,然后结束在任意景区。
    Byteasar 的旅游习惯比较特殊,一旦他路过了一个景区,他就一定会进去参观,并且他永远不会参
    观同一个景区两次。所以他想知道,有多少种可行的旅游路线,使得他可以恰好参观 4 个景区呢?即,
    有多少条简单路径恰好经过了 4 个点。
    Input
    第一行包含两个整数 n,表示景区的总数。
    第 2 至第 n + 1 行,每行一个长度为 n 的 01 字符串,第 i + 1 行第 j 个字符为 0 表示 i 和 j 之间
    没有道路,为 1 表示有一条道路。
    输入数据保证 (i, j) 的连接情况等于 (j, i) 的连接情况,且 (i, i) 恒为 0。
    Output
    输出一行一个整数,即可行的路线总数。

    n<=1500

    记得开long long!!!        记得开long long!!!         记得开long long!!!

    40pts(直接枚举第一二三四个点,判断是否重复,是否按顺序连通——O(n^4))

    70pts(枚举其中的第一二三个点,第四个点个数就是第三个点的度数-1,当然考虑环的情况,如果第三个点和第一个点连通,要再1   要开long long 比赛的时候因为这个丢掉30分) ——O(n^3)

    100ptsbitset优化,对于每个类似于a-b-c-d的四元组我们枚举中间的俩元素b-c
        然后对于这一组元素对答案的贡献为(du[b]-1)*(du[c]-1)-包含b-c这组元素的三元环个数
       枚举三元环的个数 ,其中两个元素b-c已经确定,只要再找一个元素x同时满足x-b连通 且x-c连通即可
       然而找到元素x最简单的方法即O(n) 枚举,但是这样的话时间复杂度重新退化为O(n^3)
       于是考虑bitset优化, 假设与b相连的元素集合为s[b],
       则三元环个数即为(s[b]&s[c]).count()(两集合并集中1的个数,即同时与b,c相连)——O(n^3/32)

        本题对于Pascal选手还是不太友好的,但手动bitset也不是不可以/滑稽

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<algorithm>
     5 #include<bitset> 
     6 #define int long long //懒人专用 
     7 using namespace std;
     8 inline int read(){
     9     char chr=getchar();    int f=1,ans=0;
    10     while(!isdigit(chr)) {if(chr=='-') f=-1;chr=getchar();}
    11     while(isdigit(chr))  {ans=(ans<<3)+(ans<<1);ans+=chr-'0';chr=getchar();}
    12     return ans*f;
    13 }
    14 void write(int x){
    15     if(x<0) putchar('-'),x=-x;
    16     if(x>9) write(x/10);
    17     putchar(x%10+'0');
    18 }
    19 int n,a[1505][1505],du[1505];
    20 char s[1505];
    21 long long ans=0;
    22 bitset<1505> ss[1505];
    23 signed main(){
    24     freopen("tour.in","r",stdin);
    25     freopen("tour.out","w",stdout);
    26     n=read();
    27     for(register int i=1;i<=n;++i){
    28         scanf("%s",s+1);
    29         for(register int j=1;j<=n;++j)
    30             if(s[j]=='0') a[i][j]=0;else a[i][j]=1,du[i]++;
    31     }
    32     if(n<=50)//①40pts,这里码风可能不太友好(考试的时候为了卡常)当然了,如果100分方法看懂了可以略过前两种部分分的方法
    33     for(register int i=1;i<=n;++i)
    34         for(register int j=1;j<=n;++j){if(i!=j&&a[i][j])
    35             for(register int k=1;k<=n;++k){if(j!=k&&i!=k&&a[j][k])
    36                 for(register int l=1;l<=n;++l){if(i!=l&&j!=l&&k!=l&&a[k][l])++ans;}}}
    37     else if(n<=300){
    38 //②70pts
    39         for(register int i=1;i<=n;++i)
    40             for(register int j=1;j<=n;++j){
    41                 if(i==j) continue;
    42                 if(!a[i][j]) continue;
    43                 for(register int k=1;k<=n;++k){
    44                     if(i==k||j==k) continue;
    45                     if(!a[j][k]) continue;
    46                     ans+=du[k]-1;
    47                     if(a[k][i]) ans--;
    48                 }
    49             }
    50     }else{
    51 //③100pts
    52         for(int i=1;i<=n;i++)
    53             for(int j=1;j<=n;j++)
    54                 if(a[i][j]==0) ss[i][j]=0;else ss[i][j]=1;
    55         for(int i=1;i<=n;i++)
    56             for(int j=1;j<=n;j++){
    57                 if(!a[i][j]) continue;
    58                 if(i==j) continue;
    59                 ans+=(du[i]-1)*(du[j]-1)-(ss[i]&ss[j]).count();
    60             }
    61     }
    62     write(ans);
    63     return 0;
    64 }

     Problem C. Walk(walk.c/cpp/pas)

    考试妥妥的打暴力系列

    在比特镇一共有 n 个街区,编号依次为 1 到 n,它们之间通过若干条单向道路连接。
    比特镇的交通系统极具特色,除了 m 条单向道路之外,每个街区还有一个编码 vali,不同街区可能
    拥有相同的编码。如果 vali and valj = valj,即 vali 在二进制下与 valj 做与运算等于 valj,那么也会
    存在一条额外的从 i 出发到 j 的单向道路。
    Byteasar 现在位于 1 号街区,他想知道通过这些道路到达每一个街区最少需要多少时间。因为比特
    镇的交通十分发达,你可以认为通过每条道路都只需要 1 单位时间。
    Input
    第一行包含两个正整数 n, m,表示街区的总数以及道路的总数。
    第二行包含 n 个正整数 val1, val2, ..., valn,分别表示每个街区的编码。
    接下来 m 行,每行包含两个正整数 ui
    , vi,表示一条单向道路,起点为 ui,终点为 vi。
    Output
    输出 n 行,每行一个整数,其中第 i 行输出到达第 i 个街区的最少时间,如果无法到达则输出 −1

    ①20分,直接求就好了

    ②40分,O(n^2)建图,O(n)BFS求最短路

    ③70分,考虑重新构图,新增1<<15个点,枚举子集(O(n^3)),向点 i 向它所有的子集连一条权值为 0 的有向边,然后在向原图中连回去,可能表达不太对,画个图意会一下//待会儿FFT来说又怪语文老师

    ④100分,还是新建图,点i 只需要向点 i 去掉某一位的 1 的点连边,这样边的数量得到有效控制

     1 #pragma GCC optimize(2)
     2 #include<iostream>
     3 #include<cstdio>
     4 #include<cstring>
     5 #include<algorithm>
     6 #include<queue>
     7 #define ll long long
     8 using namespace std;
     9 inline int read(){
    10     char chr=getchar();    int f=1,ans=0;
    11     while(!isdigit(chr)) {if(chr=='-') f=-1;chr=getchar();}
    12     while(isdigit(chr))  {ans=(ans<<3)+(ans<<1);ans+=chr-'0';chr=getchar();}
    13     return ans*f;
    14 }
    15 void write(int x){
    16     if(x<0) putchar('-'),x=-x;
    17     if(x>9) write(x/10);
    18     putchar(x%10+'0');
    19 }
    20 const int N=1300005;
    21 int val[N],cnt;
    22 int n,m,ver[N<<1],head0[N<<1],head1[N<<1],nxt[N<<1],dis[N<<1],tot=0,x,y,hd=1,tl=0,q[N];
    23 bool vis[N<<1];
    24 inline void add1(int x,int y){ver[++tot]=y;nxt[tot]=head1[x];head1[x]=tot;}
    25 inline void add0(int x,int y){ver[++tot]=y;nxt[tot]=head0[x];head0[x]=tot;}
    26 void Run(int x,int w){
    27   if(dis[x]>=0)return;
    28   dis[q[++tl]=x]=w;
    29   for(int i=head0[x];i;i=nxt[i])     Run(ver[i],w);
    30   if(x>=cnt) return;
    31   for(int i=0;i<20;i++)if(x>>i&1)    Run(x^(1<<i),w);
    32 }
    33 int main(){
    34     freopen("walk.in","r",stdin);
    35     freopen("walk.out","w",stdout);
    36     n=read(),m=read();cnt=1<<20;
    37     for(int i=1;i<=n;i++)    x=read(),add1(i+cnt,x),add0(x,i+cnt);
    38     for(int i=1;i<=m;i++)   x=read(),y=read(),add1(x+cnt,y+cnt);
    39     for(int i=1;i<=n+cnt;i++) dis[i]=-1;
    40     Run(cnt+1,0);
    41     while(hd<=tl)for(int i=head1[x=q[hd++]];i;i=nxt[i])Run(ver[i],dis[x]+1);
    42     for(int i=1;i<=n;i++) write(dis[i+cnt]),puts("");
    43     return 0;
    44 }
  • 相关阅读:
    在博客园安了新家,开心哦!
    ViewState与Session的区别(转)
    什么是web.config .net配置文件介绍
    YUI Grid CSS的优雅设计(转)
    css reset
    Windows、(*)nux回忆录 作为架构师的你 值得拥有 O(∩_∩)O~
    .NET互联网网站架构(非原创)
    重构与设计解析(非原创)
    SQL Server2005索引简介
    mongodb相关
  • 原文地址:https://www.cnblogs.com/zhenglw/p/10326669.html
Copyright © 2011-2022 走看看