zoukankan      html  css  js  c++  java
  • [考试反思]0920csp-s模拟测试48:弱小

    注:T1全场46个人里42个AC了。

    %%%zkt也AK了呢越来越强啊

    我是真的越来越弱了吗?

    我到底在干什么。。。

    在难度递增的题里分数递增。。。

    考试过程大体还好,但是如此快速地WA掉T1也真是蠢得不行了。

    T2没想到bitset,对1500这种数据范围还是不敏感。

    T3想出来还是挺快的,注意观察数据范围就万事大吉。(二进制相关的题我的得分平时都不太低,是撞大运了?)

    然后给T2和T3都上了个对拍,T3出锅了剩30分幸亏改过来了。

    然而感觉T1实在太傻逼了暴力和正解是一个复杂度的就没打,手模几个样例就结束了。

    题目的样例和手模的样例都在字串和子序列下答案相同。。。

    但是这次不是看错题了,我也知道是子串,但是打到一半没过脑子就飘移到子序列上了。(因为原来做过一个那个题)

    我,傻子,太弱了。

    不要轻视最简单的题,你A不掉的!该打对拍还是要对拍。

    bitset是出题人很喜欢的一个考点,1500的数据范围可能指向n3/32

    T1:String Master

    简单dp或硬匹配。

    自行找不同?EXP++

     1 #include<cstdio>
     2 #include<iostream>
     3 using namespace std;
     4 char a[305],b[305];int n,k,dp[305][305][305];
     5 int main(){
     6     scanf("%d%d%s%s",&n,&k,a+1,b+1);
     7     for(int i=1;i<=n;++i)for(int j=1;j<=n;++j)for(int l=0;l<=k;++l){
     8         if(a[i]==b[j])dp[i][j][l]=max(dp[i][j][l],dp[i-1][j-1][l]+1);
     9         if(l)dp[i][j][l]=max(dp[i][j][l],dp[i-1][j-1][l-1]+1);
    10         dp[i][j][l]=max(dp[i][j][l],max(dp[i-1][j][l],dp[i][j-1][l]));
    11     }printf("%d
    ",dp[n][n][k]);
    12 }
    10分的子序列版本
     1 #include<cstdio>
     2 #include<iostream>
     3 using namespace std;
     4 char a[305],b[305];int n,k,dp[305][305][305],ans;
     5 int main(){
     6     scanf("%d%d%s%s",&n,&k,a+1,b+1);
     7     for(int i=1;i<=n;++i)for(int j=1;j<=n;++j)for(int l=0;l<=k;++l){
     8         if(a[i]==b[j])dp[i][j][l]=max(dp[i][j][l],dp[i-1][j-1][l]+1);
     9         if(l)dp[i][j][l]=max(dp[i][j][l],dp[i-1][j-1][l-1]+1);
    10         ans=max(dp[i][j][l],ans);
    11     }printf("%d
    ",ans);
    12 }
    100分的子串版本

    思路积累:

    • 细致。

    T2:Tourist Attaction

    容斥。所有路径-第1,3个点相同的路径-第2,4个点相同的路径+第13和24分别相同的路径-三元环数×6。

     1 #include<cstdio>
     2 int n,d[1505];long long dp[5][1505],ans;char s[1505][1505];
     3 int main(){
     4     scanf("%d",&n);
     5     for(int i=1;i<=n;++i)scanf("%s",s[i]+1);
     6     for(int i=1;i<=n;++i)dp[1][i]=1;
     7     for(int i=1;i<=n;++i)for(int j=1;j<=n;++j)if(s[i][j]=='1')d[i]++;
     8     for(int t=2;t<=4;++t)for(int i=1;i<=n;++i)for(int j=1;j<=n;++j)if(s[i][j]=='1')dp[t][i]+=dp[t-1][j];
     9     for(int i=1;i<=n;++i)ans+=dp[4][i];
    10     for(int i=1;i<=n;++i)ans-=d[i]*d[i]*2;
    11     for(int i=1;i<=n;++i)for(int j=1;j<=n;++j)if(s[i][j]=='1')ans++;
    12     for(int i=1;i<=n;++i)for(int j=i+1;j<=n;++j)if(s[i][j]=='1')
    13         for(int k=j+1;k<=n;++k)if(s[i][k]=='1'&&s[j][k]=='1')ans-=6;
    14     printf("%lld
    ",ans);
    15 }
    暴力
     1 #include<cstdio>
     2 #include<bitset>
     3 using namespace std;
     4 bitset<1501>b[1501];
     5 int n,d[1505];long long dp[5][1505],ans;char s[1505][1505];
     6 int main(){
     7     scanf("%d",&n);
     8     for(int i=1;i<=n;++i)scanf("%s",s[i]+1);
     9     for(int i=1;i<=n;++i)dp[1][i]=1;
    10     for(int i=1;i<=n;++i)for(int j=1;j<=n;++j)if(s[i][j]=='1')d[i]++;
    11     for(int t=2;t<=4;++t)for(int i=1;i<=n;++i)for(int j=1;j<=n;++j)if(s[i][j]=='1')dp[t][i]+=dp[t-1][j];
    12     for(int i=1;i<=n;++i)ans+=dp[4][i];
    13     for(int i=1;i<=n;++i)ans-=d[i]*d[i]*2;
    14     for(int i=1;i<=n;++i)for(int j=1;j<=n;++j)if(s[i][j]=='1')ans++;
    15     for(int i=1;i<=n;++i)for(int j=1;j<=n;++j)if(s[i][j]=='1')b[i][j]=1;
    16     for(int i=1;i<=n;++i)for(int j=i+1;j<=n;++j)if(b[i][j])ans-=(b[i]&b[j]).count()*2;
    17     printf("%lld
    ",ans);
    18 }
    bitset优化后就是正解

    思路积累:

    • STL bitset。32这个数字在复杂度里不可忽视!!

    T3:Walk

    观察数据范围,权值小于220,大约是1048576。既然没有出到230显然复杂度与之有关。

    题目里有特殊性质,边权都是1,那么就是一个BFS而不是Dijkstra。(然而并没有卡Dijkstra的log复杂度)

    那么每一个点只会被更新一次,那1048576也只会各被更新一次。

    存进vector里面用dfs更新即可。

     1 #include<cstdio>
     2 #include<vector>
     3 using namespace std;
     4 vector<int>v[1048578];
     5 int n,val[200005],dt[200005],m,fir[200005],l[600005],to[600005],cnt,al[1048588];
     6 int q[200005],qt;
     7 void link(int a,int b){l[++cnt]=fir[a];fir[a]=cnt;to[cnt]=b;}
     8 inline void read(register int &p,register char ch=getchar()){p=0;
     9     while(ch<'0'||ch>'9')ch=getchar();
    10     while(ch>='0'&&ch<='9')p=(p<<3)+(p<<1)+ch-48,ch=getchar();
    11 }
    12 void update(register const int num,register const int d){
    13     al[num]=1;
    14     for(register int i=0;i<v[num].size();++i)if(dt[v[num][i]]>d)dt[v[num][i]]=d,q[++qt]=v[num][i];
    15     for(register int j=num;j;j-=j&-j)if(!al[num^(j&-j)])update(num^(j&-j),d);
    16 }
    17 int main(){//freopen("t3.in","r",stdin);freopen("t3.out","w",stdout);
    18     read(n);read(m);
    19     for(int i=1;i<=n;++i)read(val[i]),v[val[i]].push_back(i);
    20     for(int i=1,x,y;i<=m;++i)read(x),read(y),link(x,y);
    21     for(int i=2;i<=n;++i)dt[i]=200001;
    22     q[qt=1]=1;
    23     for(int qh=1;qh<=qt;++qh){
    24         for(int i=fir[q[qh]];i;i=l[i])if(dt[to[i]]>dt[q[qh]]+1)dt[to[i]]=dt[q[qh]]+1,q[++qt]=to[i];
    25         if(!al[val[q[qh]]])update(val[q[qh]],dt[q[qh]]+1);
    26     }
    27     for(int i=1;i<=n;++i)printf("%d
    ",dt[i]==200001?-1:dt[i]);
    28 }
    View Code

     思路积累:

    • 边权为1的图指向BFS。
    • 二进制的子集枚举:去掉其中一位再迭代搜索(有重复,但是在每个点全场只需更新1次时复杂度是对的)
  • 相关阅读:
    地区列表
    storyboard
    快捷键2
    关于本地缓存
    深入浅出Cocoa之消息
    ARC和Non-ARC下的单例模式
    runloop原理介绍
    ARC内存管理机制详解
    解决UITableViewCell separator左侧不贴边
    UICollectionView的使用
  • 原文地址:https://www.cnblogs.com/hzoi-DeepinC/p/11561284.html
Copyright © 2011-2022 走看看