Codeforces Round #578 (Div. 2)

A.模拟。

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<iostream>
 4 #include<algorithm>
 5 #define rep(i,l,r) for (int i=(l); i<=(r); i++)
 6 typedef long long ll;
 7 using namespace std;
 8  
 9 const int N=200010;
10 char s[N];
11 int n,b[N];
12  
13 int main(){
14     scanf("%d%s",&n,s+1);
15     rep(i,1,n){
16         if (s[i]=='L') rep(j,0,9) if (!b[j]){ b[j]=1; break; }
17         if (s[i]=='R') for (int j=9; ~j; j--) if (!b[j]){ b[j]=1; break; }
18         if (s[i]>='0' && s[i]<='9') b[s[i]-'0']=0;
19     }
20     rep(i,0,9) if (b[i]) putchar('1'); else putchar('0');
21     return 0;
22 }
A

B.为了积累积木,一定是走到h[i]-k的高度。

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<iostream>
 4 #include<algorithm>
 5 #define rep(i,l,r) for (int i=(l); i<=(r); i++)
 6 typedef long long ll;
 7 using namespace std;
 8  
 9 const int N=2000010;
10 int T,n,m,k,h[N];
11  
12 int main(){
13     for (scanf("%d",&T); T--; ){
14         scanf("%d%d%d",&n,&m,&k); bool flag=0;
15         rep(i,1,n) scanf("%d",&h[i]);
16         rep(i,1,n-1){
17             if (h[i]<h[i+1]-k){
18                 if (m<h[i+1]-k-h[i]){ flag=1; break; }
19                 m-=h[i+1]-k-h[i]; continue;
20             }
21             m+=h[i]-max(h[i+1]-k,0);
22         }
23         if (flag) puts("NO"); else puts("YES");
24     }
25     return 0;
26 }
B

C.都知道怎么做,关键就是把它变成代码。

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<iostream>
 4 #include<algorithm>
 5 #define rep(i,l,r) for (int i=(l); i<=(r); i++)
 6 typedef long long ll;
 7 using namespace std;
 8  
 9 ll n,m,s1,s2,sx,sy,ex,ey;
10 int Q;
11  
12 ll gcd(ll a,ll b){ return b ? gcd(b,a%b) : a; }
13  
14 int main(){
15     cin>>n>>m>>Q;
16     rep(i,1,Q){
17         cin>>sx>>sy>>ex>>ey; s1=n/gcd(n,m); s2=m/gcd(n,m);
18         if (sx==1 && ex==1) puts((sy-1)/s1==(ey-1)/s1?"YES":"NO");
19         else if (sx==2 && ex==2) puts((sy-1)/s2==(ey-1)/s2?"YES":"NO");
20         else if (sx==1 && ex==2) puts((sy-1)/s1==(ey-1)/s2?"YES":"NO");
21         else if (sx==2 && ex==1) puts((sy-1)/s2==(ey-1)/s1?"YES":"NO");
22     }
23     return 0;
24 }
C

D.若想将一行全部变成白色,则选取矩形的左上角是在一个矩形里的,一列也一样。于是这就是个矩形加问题,二维差分即可。

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<iostream>
 4 #include<algorithm>
 5 #define rep(i,l,r) for (int i=(l); i<=(r); i++)
 6 typedef long long ll;
 7 using namespace std;
 8  
 9 const int N=2010;
10 int n,k;
11 char s[N][N];
12 int a[N][N],b[N][N];
13  
14 int main(){
15     scanf("%d%d",&n,&k);
16     rep(i,1,n) scanf("%s",&s[i][1]);
17     int ans=0;
18     rep(i,1,n){
19         int mn=n+1,mx=0;
20         rep(j,1,n) if (s[i][j]=='B') mn=min(mn,j),mx=max(mx,j);
21         if (mn==n+1) ++ans;
22         else if (mx-mn+1>k) continue;
23         else{
24             int x=max(1,i-k+1),y=max(1,mx-k+1);
25             rep(j,x,i) a[j][y]++,b[j][mn+1]++;
26         }
27     }
28     rep(i,1,n){
29         int mn=n+1,mx=0;
30         rep(j,1,n) if (s[j][i]=='B') mn=min(mn,j),mx=max(mx,j);
31         if (mn==n+1) ++ans;
32         else if (mx-mn+1>k) continue;
33         else{
34             int x=max(1,mx-k+1),y=max(1,i-k+1);
35             rep(j,x,mn) a[j][y]++,b[j][i+1]++;
36         }
37     }
38     int Ans=0;    
39     rep(i,1,n){
40         int tot=0;
41         rep(j,1,n){
42             tot+=a[i][j]; tot-=b[i][j];
43             Ans=max(Ans,tot+ans);
44         }
45     }
46     cout<<Ans;
47     return 0;
48 }
D

E.一个做法是依次做,比较前后缀是否相同时用Hash。另一个做法是每次对新加入的串求KMP中的fail数组,然后扫一遍求出前面合成出的串与新加入的串的最长匹配长度。

 1 #include<string>
 2 #include<cstdio>
 3 #include<algorithm>
 4 #include<iostream>
 5 #define rep(i,l,r) for (int i=(l); i<=(r); i++)
 6 using namespace std;
 7  
 8 const int p1=131,p2=998244353;
 9 int n;
10 string s,res;
11  
12 int main(){
13     for (scanf("%d",&n); n--; ){
14         cin>>s;
15         int l=0,r=0,p=1,c=0,ed=min(res.size(),s.size())-1,len=res.size();
16         rep(i,0,ed){
17             l=(l+1ll*res[len-i-1]*p)%p2,r=(1ll*r*p1+s[i])%p2,p=1ll*p*p1%p2;
18             if (l==r) c=i+1;
19         }
20         res+=s.substr(c);
21     }
22     cout<<res<<endl;
23     return 0;
24 }
E(Hash)
 1 #include<string>
 2 #include<cstdio>
 3 #include<algorithm>
 4 #include<iostream>
 5 #define rep(i,l,r) for (int i=(l); i<=(r); i++)
 6 using namespace std;
 7  
 8 const int N=1000010;
 9 string res,s;
10 int n,fail[N];
11  
12 int main(){
13     ios::sync_with_stdio(0); cin.tie(0);
14     cin>>n>>res;
15     while (--n){
16         cin>>s; fail[0]=0;
17         for (int i=1,j=0; i<(int)s.length(); i++){
18             fail[i]=0;
19             while (j>0 && s[i]!=s[j]) j=fail[j-1];
20             if (s[i]==s[j]) fail[i]=++j;
21         }
22         int j=0;
23         for (int i=max(0,(int)res.length()-(int)s.length()); i<(int)res.length(); i++){
24             while (j>0 && res[i]!=s[j]) j=fail[j-1];
25             if (res[i]==s[j]) j++;
26         }
27         for (; j<(int)s.length(); j++) res+=s[j];
28     }
29     cout<<res<<endl;
30     return 0;
31 }
E(KMP)

F.每个点拆成2520份然后直接跑记忆化搜索即可。

 1 #include<vector>
 2 #include<cstdio>
 3 #include<algorithm>
 4 #include<iostream>
 5 #define rep(i,l,r) for (int i=(l); i<=(r); i++)
 6 using namespace std;
 7  
 8 const int N=1010,mod=2520;
 9 int n,Q,x,y,dep,f[N][mod],tim[N],k[N];
10 vector<int>to[N];
11  
12 int dfs(int x,int y){
13     if (f[x][y]>0) return f[x][y];
14     if (f[x][y]<0){
15         int sz=0;
16         rep(i,1,n) sz+=tim[i]<=f[x][y];
17         return f[x][y]=sz;
18     }
19     f[x][y]=tim[x]=--dep;
20     return f[x][y]=dfs(to[x][(y+k[x])%to[x].size()],(y+k[x])%mod);
21 }
22  
23 int main(){
24     ios::sync_with_stdio(0); cin.tie(0);
25     cin>>n;
26     rep(i,1,n) cin>>k[i],k[i]=(k[i]%mod+mod)%mod;
27     rep(i,1,n) for (cin>>x; x--; ) cin>>y,to[i].push_back(y);
28     for (cin>>Q; Q--; ) cin>>x>>y,y=(y%mod+mod)%mod,cout<<dfs(x,y)<<endl;
29     return 0;
30 }
F

 

posted @ 2019-08-18 14:14  HocRiser  阅读(269)  评论(0编辑  收藏  举报