[考试反思]1108csp-s模拟测试105: 傀儡

评测机是真的老了。。。

我的脑力也老了。。。

昨天写完T3之后感觉脑子就留在那了,直到现在还感觉自己神志不清。。。

T1OJ上过了(跑得挺慢但是的确过了),但是文件评测同样是开O2居然只剩下70分。。。

T3全是1.02秒左右的TLE掉了25分。。。

没什么想说的,脑子不在。

for循环用加法实现乘法。大神操作我自己都看不懂。

论玩STL会变成什么样子。int映射为vector再迭代器遍历。

然而那个map除了增加复杂度什么用都没有。。。

 

T1:小W的魔术

这次还真的没有打表找规律。直接按照定义式子就出来了。

“枚举”左边匹配了i位,为了防止重复,第i+1位不能匹配。然后累加所有合法的串。

 1 #include<cstdio>
 2 #define mod 998244353
 3 #define LL long long
 4 LL qpow(LL b,LL t,LL a=1){for(;t;t>>=1,b=b*b%mod)if(t&1)a=a*b%mod;return a;}
 5 long long n,ans;int l;char s[1000005];
 6 main(){
 7     freopen("magic.in","r",stdin);
 8     freopen("magic.out","w",stdout);
 9     scanf("%lld%s",&n,s+1);
10     while(s[l+1])l++;
11     if(n==l)return printf("%lld\n",qpow(26,n)-1),0;
12     for(int i=0;i<l;++i)ans=(ans+25*qpow(26,n-l-1))%mod;
13     printf("%lld\n",(qpow(26,n)-(ans+qpow(26,n-l))+mod+mod)%mod);
14 }
快乐乘法

 

T2:小Y的图

《货车运输》原题。最小生成树+随便一个树上求值。

当然离线下来并查集乱搞也行。因为没有开C++11所以没有unordered_map。复杂度$O(nlog^2n)$了。

把map去掉就对了。

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 map<int,vector<int> >M[300005];
 4 int f[300005],ans[300005],n,m,q;
 5 struct Edge{
 6     int a,b,l;
 7     friend bool operator<(Edge a,Edge b){
 8         return a.l<b.l;
 9     }
10 }E[300005];
11 int find(int p){return f[p]==p?p:f[p]=find(f[p]);}
12 void merge(int a,int b,int w){
13     vector<int>&V=M[a][b];
14     for(int i=0;i<V.size();++i)ans[V[i]]=w;
15     V=M[b][a];
16     for(int i=0;i<V.size();++i)ans[V[i]]=w;
17     if(M[a].size()<M[b].size())swap(a,b);
18     for(map<int,vector<int> >::iterator it=M[b].begin();it!=M[b].end();++it){
19         int x=find((*it).first);V=(*it).second;if(b==x)continue;
20         for(int i=0;i<V.size();++i)if(ans[V[i]]==-1)M[a][x].push_back(V[i]);
21     }f[b]=a;
22 }
23 int main(){
24     freopen("graph.in","r",stdin);
25     freopen("graph.out","w",stdout);
26     scanf("%d%d%d",&n,&m,&q);
27     for(int i=1;i<=n;++i)f[i]=i;
28     for(int i=1;i<=m;++i)scanf("%d%d%d",&E[i].a,&E[i].b,&E[i].l);
29     for(int i=1,a,b;i<=q;++i)scanf("%d%d",&a,&b),M[a][b].push_back(i),M[b][a].push_back(i),ans[i]=-1*(a!=b);
30     sort(E+1,E+1+m);
31     for(int i=1;i<=m;++i)if(find(E[i].a)!=find(E[i].b))merge(f[E[i].a],f[E[i].b],E[i].l);
32     for(int i=1;i<=q;++i)printf("%d\n",ans[i]);
33 }
View Code

 

T3:小L的数

答案不超过4。01,02,04,08可以构成所有数。

喜欢的数只有45种:01,02...09,12,13,...19,23,24,...,29,34,35,...,39,45,46,...,49,56,57,58,59,67,68,69,78,79,89。

check答案是否为1,2,3,如果都不是答案就是4。

外层枚举喜欢的数,一共有$C_{45}^3$种。内层check(答案为123的做法是一样的,以3为例)

数位dp。(记忆化搜索)。dp[i][j][k]表示到了第i位,这一位的前导0状态为j($2^3$状压状态),当前位需要进位k($0 \leq k \leq 2$)

转移就是枚举每一个喜欢的数的选用情况($3^3$,因为要注意到前导0)

转移比较简单粗暴,按照含义来一直写就行了。

觉得循环展开是没有脸的行为,所以就被卡常了。所以卡了卡加了许多个break也就卡过了。

代码2k其实也能下来。

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 #define ri register int
 4 long long pw[19];int f[19];bool al[19][8][3];
 5 bool dfs(ri ws,ri st,ri up,ri A,ri B,ri C,ri D,ri E,ri F){
 6     if(ws==18)memset(al,0,sizeof al);
 7     if(ws==-1&&up==0)return 1;
 8     if(ws==-1&&up)return 0;
 9     if(al[ws][st][up])return 0;
10     ri g=(up<<3)+(up<<1)+f[ws],nst=0;
11     for(ri i=0;i<3;++i){
12         if((st&1)&&i==2)break;
13         if(A==0&&i==2)break;
14         ri x=i?B:A;if(i==2)x=0,nst^=nst&1;else nst|=1;
15         if(x>g||x+20<g)continue;
16         for(ri j=0;j<3;++j){
17             if((st&2)&&j==2)break;
18             if(C==0&&j==2)break;
19             if(!C&&!D&&j)break;
20             ri y=j?D:C;if(j==2)y=0,nst^=nst&2;else nst|=2;
21             if(x+y>g||x+y+11<g)continue;
22             for(ri k=0;k<3;++k){
23                 if((st&4)&&k==2)break;
24                 if(E==0&&k==2)break;
25                 ri z=k?F:E;if(k==2)z=0;
26                 z+=x+y;
27                 if(z>g||z+2<g)continue;
28                 nst|=st;
29                 if(k!=2)nst|=4;
30                 if(z==g){if(dfs(ws-1,nst,0,A,B,C,D,E,F))return 1;}
31                 else if(z==g-1){if(dfs(ws-1,nst,1,A,B,C,D,E,F))return 1;}
32                 else if(dfs(ws-1,nst,2,A,B,C,D,E,F))return 1;
33             }
34         }
35     }
36     al[ws][st][up]=1;return 0;
37 }
38 bool chk1(){
39     for(ri i=0;i<=9;++i)for(ri j=i+1;j<=9;++j)if(dfs(18,0,0,i,j,0,0,0,0))return 1;
40     return 0;
41 }
42 bool chk2(){
43     for(ri i=0;i<=9;++i)for(ri j=i+1;j<=9;++j)
44         for(ri k=i;k<=9;++k)for(ri l=max(k+1,i==k?j+1:0);l<=9;++l)
45             if(dfs(18,0,0,i,j,k,l,0,0))return 1;
46     return 0;
47 }
48 bool chk3(){
49     for(ri i=0;i<=9;++i)for(ri j=i+1;j<=9;++j)
50         for(ri k=i+1;k<=9;++k)for(ri l=max(k+1,i==k?j+1:0);l<=9;++l)
51             for(ri m=k+1;m<=9;++m)for(ri n=max(m+1,k==m?l+1:0);n<=9;++n)
52                 if(dfs(18,0,0,i,j,k,l,m,n))return 1;
53     return 0;
54 }
55 int main(){
56     freopen("number.in","r",stdin);
57     freopen("number.out","w",stdout);
58     ri t;scanf("%d",&t);
59     pw[0]=1;for(ri i=1;i<18;++i)pw[i]=pw[i-1]*10;
60     for(int i=1;i<=t;++i){
61         long long x;scanf("%lld",&x);
62         for(ri i=0;i<18;++i)f[i]=x/pw[i]%10;
63         if(chk1())puts("1");
64         else if(chk2())puts("2");
65         else if(chk3())puts("3");
66         else puts("4");
67     }
68 }
View Code
posted @ 2019-11-08 16:06  DeepinC  阅读(345)  评论(7编辑  收藏  举报