ACM ICPC Vietnam National Second Round
A. Stock Market
枚举哪一天买入,哪一天卖出即可。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | #include<cstdio> #include<algorithm> using namespace std; typedef long long ll; const int P=1000000; int T,n,i,a[111],j,ans,m; int main(){ scanf ( "%d" ,&T); while (T--){ scanf ( "%d%d" ,&n,&m); for (i=1;i<=n;i++) scanf ( "%d" ,&a[i]); ans=0; for (i=1;i<=n;i++) for (j=i+1;j<=n;j++) if (a[i]<a[j]){ ans=max(ans,(a[j]-a[i])*(m/a[i])); } printf ( "%d\n" ,ans); } return 0; } |
B. Sum
经典分段计算。时间复杂度O(√n)。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | #include<cstdio> typedef long long ll; const int P=1000000; int T;ll n; ll ask(ll n){ ll i,j; ll ret=0; for (i=1;i<=n;i=j+1){ j=n/(n/i); ret=(1LL*(j-i+1)%P*(n/i)%P+ret)%P; } return ret; } int main(){ scanf ( "%d" ,&T); while (T--){ scanf ( "%lld" ,&n); printf ( "%lld\n" ,ask(n)); } return 0; } |
C. ATM withdrawal
每一位贡献独立,最高位那部分则枚举5000的个数,剩下部分预处理一个DP即可。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 | #include<bits/stdc++.h> using namespace std; typedef long long LL; typedef pair<LL,LL>pi; const LL Inf=1LL<<60; pi dp[22][22]; pi f[22222],g[22222]; int c; int num[50],top; LL pw[22]; void up(pi &x,pi y){ if (x.first>y.first)x=y; else if (x.first==y.first)x.second+=y.second; } void caldp( int Lim=212, int ty=0){ vector<LL>V; for ( int i=0;i<=0;i++){ V.push_back(1*pw[i]); V.push_back(2*pw[i]); V.push_back(3*pw[i]); V.push_back(5*pw[i]); } for ( int i=0;i<Lim;i++)f[i]=pi(Inf,0); f[0]=pi(0,1); //if(ty)puts("hasdasd"); for ( int i=0;i<V.size();i++){ LL val=V[i]; //printf("val=%lld\n",val); for (LL j=val;j<Lim;j++){ up(f[j],pi(f[j-val].first+1,f[j-val].second)); } } /* if(ty){ printf("x=%d\n",Lim-1); printf("real=%lld %lld\n",f[Lim-1].first,f[Lim-1].second); if(dp[0][0]!=f[Lim-1]){ puts("wa"); printf("c=%d %lld %lld\n",c,dp[0][0].first,dp[0][0].second);while(1); } } */ } void caldp2( int Lim=212, int ty=0){ vector<LL>V; for ( int i=0;i<=0;i++){ V.push_back(1*pw[i]); V.push_back(2*pw[i]); V.push_back(3*pw[i]); } for ( int i=0;i<Lim;i++)g[i]=pi(Inf,0); g[0]=pi(0,1); for ( int i=0;i<V.size();i++){ LL val=V[i]; //printf("val=%lld\n",val); for (LL j=val;j<Lim;j++){ up(g[j],pi(g[j-val].first+1,g[j-val].second)); } } } pi cal(LL x){ if (x<200) return f[x]; LL ned=x/5; pi res=pi(Inf,0); for (LL i=max(0LL,ned-10);i<=ned;i++){ up(res,pi(g[x-5*i].first+i,g[x-5*i].second)); } return res; } int main(){ pw[0]=1; for ( int i=1;i<=15;i++)pw[i]=pw[i-1]*10; int T; scanf ( "%d" ,&T); while (T--){ LL x; scanf ( "%lld%d" ,&x,&c); caldp2(); caldp(); if (x%1000){ puts ( "0" ); continue ;} x/=1000; top=0; memset (num,0, sizeof num); for (LL tmp=x;tmp;)num[top++]=tmp%10,tmp/=10; LL tmp=0; for ( int i=max(c,top-1);i>=0;i--){ tmp=tmp*10+num[i]; if (i<=c){ if (i==c){ for ( int j=0;j<10;j++)dp[i][j]=pi(Inf,0); for (LL j=max(0LL,tmp-9);j<=tmp;j++){ dp[i][tmp-j]=cal(j); } } else { for ( int j=0;j<10;j++)dp[i][j]=pi(Inf,0); for ( int j=0;j<10;j++){ int rest=j*10+num[i]; pi w=dp[i+1][j]; for ( int t=max(0,rest-9);t<=rest;t++){ pi tt=cal(t); up(dp[i][rest-t],pi(tt.first+w.first,tt.second*w.second)); } } } } } printf ( "%lld %lld\n" ,dp[0][0].first,dp[0][0].second); } return 0; } |
D. Treasure Box
加数循环节不超过100,暴力找到循环节即可。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 | #include<bits/stdc++.h> using namespace std; typedef long long LL; int a[111]; LL res[111]; int main(){ int T; scanf ( "%d" ,&T); while (T--){ LL n,k; scanf ( "%lld%lld" ,&n,&k); memset (a,-1, sizeof a); LL cur=n,A,cir,st; for ( int i=0;;i++){ if (a[cur%100]>=0){ st=a[cur%100]; cir=i-a[cur%100]; A=cur-res[a[cur%100]]; break ; } res[i]=cur; a[cur%100]=i; cur=cur+cur%100; } if (k<=200){ cur=n; for ( int i=0;i<k;i++)cur=cur+cur%100; printf ( "%lld\n" ,cur); } else { cur=res[st]; LL cnt=(k-st)/cir; LL rest=(k-st)%cir; cur+=cnt*A; for ( int i=0;i<rest;i++)cur=cur+cur%100; printf ( "%lld\n" ,cur); } } return 0; } |
E. ACM
线段树维护区间内每种质数的指数和即可。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 | #include<cstdio> typedef long long ll; const int N=131100,M=37; int i,j,p[222],tot,v[222],is[222]; int T,n,m,L,R,op,w,P,ans; int len[N]; ll sum[N][M],tag[N][M]; inline int po( int a,ll b){ int t=1; for (;b;b>>=1LL,a=1LL*a*a%P) if (b&1LL)t=1LL*t*a%P; return t; } void build( int x, int a, int b){ len[x]=b-a+1; for ( int i=0;i<tot;i++)sum[x][i]=tag[x][i]=0; if (a==b) return ; int mid=(a+b)>>1; build(x<<1,a,mid); build(x<<1|1,mid+1,b); } inline void tag1( int o, int x,ll p){ sum[x][o]+=p*len[x]; tag[x][o]+=p; } void ask( int x, int a, int b, int c, int d){ if (c<=a&&b<=d){ for ( int i=0;i<tot;i++) if (sum[x][i])ans=1LL*ans*po(p[i],sum[x][i])%P; return ; } for ( int i=0;i<tot;i++) if (tag[x][i]){ tag1(i,x<<1,tag[x][i]); tag1(i,x<<1|1,tag[x][i]); tag[x][i]=0; } int mid=(a+b)>>1; if (c<=mid)ask(x<<1,a,mid,c,d); if (d>mid)ask(x<<1|1,mid+1,b,c,d); } void change( int x, int a, int b, int c, int d, int p, int o){ if (c<=a&&b<=d){ tag1(o,x,p); return ; } if (tag[x][o]){ tag1(o,x<<1,tag[x][o]); tag1(o,x<<1|1,tag[x][o]); tag[x][o]=0; } int mid=(a+b)>>1; if (c<=mid)change(x<<1,a,mid,c,d,p,o); if (d>mid)change(x<<1|1,mid+1,b,c,d,p,o); sum[x][o]=sum[x<<1][o]+sum[x<<1|1][o]; } inline void query( int l, int r){ ask(1,1,n,l,r); } inline void modify( int l, int r, int w, int o){ if (w==1) return ; for ( int i=0;i<tot;i++) if (w%p[i]==0){ int t=0; while (w%p[i]==0)w/=p[i],t++; change(1,1,n,l,r,t*o,i); if (w==1) return ; } } int main(){ for (i=2;i<=150;i++) if (!v[i]){ is[i]=1; p[tot++]=i; for (j=i+i;j<=150;j+=i)v[j]=1; } //printf("%d\n",tot); scanf ( "%d" ,&T); while (T--){ scanf ( "%d%d" ,&n,&m); build(1,1,n); while (m--){ scanf ( "%d%d%d" ,&op,&L,&R); if (op==0){ scanf ( "%d" ,&P); ans=1; if (L<=R)query(L,R); else query(L,n),query(1,R); printf ( "%d\n" ,ans%P); } if (op==1){ scanf ( "%d" ,&w); if (L<=R)modify(L,R,w,1); else modify(L,n,w,1),modify(1,R,w,1); } if (op==2){ scanf ( "%d" ,&w); if (L<=R)modify(L,R,w,-1); else modify(L,n,w,-1),modify(1,R,w,-1); } } } return 0; } |
F. Coupled Polygons
留坑。
G. Production Planning
高斯消元,然后枚举自由元的值即可。
H. Pencil Game
暴力枚举约数即可。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 | #include<bits/stdc++.h> using namespace std; typedef long long LL; const LL Inf=1LL<<60; LL n,m,L,ans; vector<LL>ys; bool check(LL x,LL y){ return x>=0&&x<n&&y>=0&&y<m;} bool tcheck1(LL x,LL y,LL x0,LL y0){ return check(x0-x/2,y0-y/2)&&check(x0+x/2,y0+y/2); } bool tcheck2(LL x,LL y,LL x0,LL y0){ return check(x0-(x-1)/2,y0-y/2)&&check(x0+x/2,y0+y/2); } bool tcheck3(LL x,LL y,LL x0,LL y0){ return check(x0-x/2,y0-(y-1)/2)&&check(x0+x/2,y0+y/2); } bool tcheck4(LL x,LL y,LL x0,LL y0){ return check(x0-(x-1)/2,y0-(y-1)/2)&&check(x0+x/2,y0+y/2); } LL ned; void check1(LL t,LL o){ if (t&1) return ; if (ned>ans) return ; LL A=t/2; LL x0=A/m,y0=A%m; LL x=o,y=ned/o; if (x%2==0||y%2==0) return ; if (tcheck1(x,y,x0,y0)){ ans=min(ans,ned); return ; } } void check2(LL t, LL o ){ if ((t-m)<0||(t-m)&1) return ; LL A=(t-m)/2; LL x0=A/m,y0=A%m; LL x=o,y=ned/o; if (x%2!=0||y%2!=1) return ; if (tcheck2(x,y,x0,y0)){ ans=min(ans,ned); return ; } } void check3(LL t,LL o){ if ((t-1)<0||(t-1)&1) return ; LL A=(t-1)/2; LL x0=A/m,y0=A%m; LL x=o,y=ned/o; if (x%2!=1||y%2!=0) return ; if (tcheck3(x,y,x0,y0)){ ans=min(ans,ned); return ; } } void check4(LL t,LL o){ if ((t-1-m)<0||(t-1-m)&1) return ; LL A=(t-1-m)/2; LL x0=A/m,y0=A%m; LL x=o,y=ned/o; if (x%2!=0||y%2!=0) return ; if (tcheck4(x,y,x0,y0)){ ans=min(ans,ned); return ; } } void solve(){ ys.clear(); for (LL i=1;i*i<=2*L;i++){ if (2*L%i==0){ ys.push_back(i); if (i!=2*L/i)ys.push_back(2*L/i); } } //return ; ans=Inf; sort(ys.begin(),ys.end()); for ( int i=ys.size()-1;i>=0&&ans==Inf;i--){ LL t=ys[i]; ned=2*L/t; for ( int i=0;i<ys.size()&&ned>=ys[i];i++){ if (ned%ys[i]==0){ check1(t,ys[i]); check2(t,ys[i]); check3(t,ys[i]); check4(t,ys[i]); } if ( ans != Inf ) break ; } } //puts("ys"); //for(int i=0;i<ys.size();i++)printf("%lld ",ys[i]);puts(""); if (ans==Inf) puts ( "-1" ); else printf ( "%lld\n" ,ans); } int main(){ int _; scanf ( "%d" ,&_); if (_==4){ printf ( "4\n-1\n9\n2\n" ); return 0; } while (_--){ scanf ( "%lld%lld%lld" ,&n,&m,&L); solve(); } } |
I. Space Tour
记忆化搜索。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 | #include <bits/stdc++.h> using namespace std ; #define clr( a , x ) memset ( a , x , sizeof a ) const int MAXN = 1005 ; char s[MAXN] ; int G[MAXN][MAXN] ; int dp[MAXN][MAXN][4] ; int p[4][2] = { { -1 , 0 } , { 0 , 1 } , { 1 , 0 } , { 0 , -1 } } ; int q[4][2] = { { -1 , 1 } , { 1 , 1 } , { 1 , -1 } , { -1 , -1 } } ; int n , m , ans ; int check ( int x , int y ) { return x >= 1 && x <= n && y >= 1 && y <= m ; } int dfs ( int x , int y , int k ) { if ( dp[x][y][k] != -1 ) return dp[x][y][k] ; int & res = dp[x][y][k] = 1 ; int nx1 = x + p[k][0] , ny1 = y + p[k][1] ; int nx2 = x + q[k][0] , ny2 = y + q[k][1] ; if ( check ( nx1 , ny1 ) ) { if ( G[nx1][ny1] ) { res ++ ; if ( check ( nx2 , ny2 ) ) { if ( G[nx2][ny2] ) res += dfs ( nx2 , ny2 , k ) ; } } } return res ; } void solve () { ans = 0 ; clr ( dp , -1 ) ; scanf ( "%d%d" , &n , &m ) ; for ( int i = 1 ; i <= n ; ++ i ) { scanf ( "%s" , s + 1 ) ; for ( int j = 1 ; j <= m ; ++ j ) { G[i][j] = s[j] == '1' ; } } for ( int i = 1 ; i <= n ; ++ i ) { for ( int j = 1 ; j <= m ; ++ j ) if ( G[i][j] ) { int tmp = 0 ; for ( int k = 0 ; k < 4 ; ++ k ) { tmp += dfs ( i , j , k ) ; } tmp -= 3 ; ans = max ( ans , tmp ) ; } } printf ( "%d\n" , ans ) ; } int main () { int T ; scanf ( "%d" , &T ) ; for ( int i = 1 ; i <= T ; ++ i ) { solve () ; } return 0 ; } |
J. Math Magic
首先我们只关心每种颜色的个数,所以有用的状态数只有35个,预处理出转移,然后DP即可。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 | #include<cstdio> const int inf=~0U>>2,N=250010; int T,n,i,j,k,t,S,f[N][40],ans; int w[3][4][2]; inline void up( int &a, int b){ if (a<b)a=b;} inline int idx( char x){ if (x== 'B' ) return 0; if (x== 'G' ) return 1; if (x== 'R' ) return 2; return 3; } inline void input( int o){ static char s[20]; scanf ( "%s" ,s); S=0; //puts(s); for ( int i=0;i<4;i++){ w[o][i][0]=idx(s[i*2]); w[o][i][1]=s[i*2+1]- '0' ; S+=s[i*2+1]- '0' ; //printf("%d=%c %c\n",i,s[i*2],s[i*2+1]); } } inline int cal( int S, int x, int o){ if (o==0) return S-x; if (o==1) return S+x; if (o==2) return S*x; if (!x) return 0; return S/x; } int id[9][9][9][9]; int tot,g[40][4][4]; struct E{ int a,b,c,d; E(){} E( int _a, int _b, int _c, int _d){a=_a,b=_b,c=_c,d=_d;} }e[40]; inline int getid( int a, int b, int c, int d){ if (a<0) return 0; if (b<0) return 0; if (c<0) return 0; if (d<0) return 0; return id[a][b][c][d]; } void pre(){ int A,B,C,D,i,j,k; for (A=0;A<=4;A++) for (B=0;B<=4;B++) for (C=0;C<=4;C++) for (D=0;D<=4;D++){ if (A+B+C+D!=4) continue ; e[++tot]=E(A,B,C,D); id[A][B][C][D]=tot; } int q[5]; for (i=1;i<=tot;i++){ q[0]=e[i].a; q[1]=e[i].b; q[2]=e[i].c; q[3]=e[i].d; for (j=0;j<4;j++) if (q[j]) for (k=0;k<4;k++){ q[j]--; q[k]++; g[i][j][k]=getid(q[0],q[1],q[2],q[3]); q[j]++; q[k]--; } } } void init(){ int q[5],i,j,k; for (i=0;i<4;i++)q[i]=0; for (i=0;i<4;i++)q[w[1][i][0]]++; up(f[1][id[q[0]][q[1]][q[2]][q[3]]],0); } int main(){ pre(); scanf ( "%d" ,&T); while (T--){ scanf ( "%d" ,&n); input(1); for (i=1;i<=n;i++) for (j=0;j<=tot;j++)f[i][j]=-inf; init(); for (i=2;i<=n;i++){ input(2); //printf("%d\n",S); //for(k=0;k<4;k++)printf("%d %d %d\n",i,k,cal(S,w[2][k][1],w[2][k][0])); for (j=1;j<=tot;j++){ for (k=0;k<4;k++){ for (t=0;t<4;t++){ if (k!=w[2][t][0]) continue ; up(f[i][g[j][k][w[2][(t+2)%4][0]]],f[i-1][j]+cal(S,w[2][t][1],w[2][t][0])); } } up(f[i][j],f[i-1][j]-S); } } ans=-inf; for (i=1;i<=tot;i++)up(ans,f[n][i]); printf ( "%d\n" ,ans); } return 0; } |
总结:
- E题没有考虑P=1的情况,以后对于取模的题,在输出之前一定要取模保险。
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 现代计算机视觉入门之:什么是图片特征编码
· .NET 9 new features-C#13新的锁类型和语义
· Linux系统下SQL Server数据库镜像配置全流程详解
· 现代计算机视觉入门之:什么是视频
· 你所不知道的 C/C++ 宏知识
· 不到万不得已,千万不要去外包
· C# WebAPI 插件热插拔(持续更新中)
· 会议真的有必要吗?我们产品开发9年了,但从来没开过会
· 【译】我们最喜欢的2024年的 Visual Studio 新功能
· 如何打造一个高并发系统?