zoukankan      html  css  js  c++  java
  • ACM ICPC Vietnam National Second Round

    A. Stock Market

    枚举哪一天买入,哪一天卖出即可。

    #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
    ",ans);
      }
      return 0;
    }
    

      

    B. Sum

    经典分段计算。时间复杂度$O(sqrt{n})$。

    #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
    ",ask(n));
      }
      return 0;
    }
    

      

    C. ATM withdrawal

    每一位贡献独立,最高位那部分则枚举$5000$的个数,剩下部分预处理一个DP即可。

    #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
    ",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
    ",Lim-1);
    		printf("real=%lld %lld
    ",f[Lim-1].first,f[Lim-1].second);
    		if(dp[0][0]!=f[Lim-1]){
    			puts("wa");
    			printf("c=%d %lld %lld
    ",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
    ",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
    ",dp[0][0].first,dp[0][0].second);
      }
      return 0;
    }
    

      

    D. Treasure Box

    加数循环节不超过$100$,暴力找到循环节即可。

    #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
    ",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
    ",cur);
        }
      }
      return 0;
    }
    

      

    E. ACM

    线段树维护区间内每种质数的指数和即可。

    #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
    ",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
    ",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

    暴力枚举约数即可。

    #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
    ",ans);
    }
    int main(){
    	int _;scanf("%d",&_);
    	if(_==4){
    		printf("4
    -1
    9
    2
    ");
    		return 0;
    	}
    	while(_--){
    		scanf("%lld%lld%lld",&n,&m,&L);
    		solve();
    	}
    }
    

      

    I. Space Tour

    记忆化搜索。

    #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
    " , ans ) ;
    }
    
    int main () {
    	int T ;
    	scanf ( "%d" , &T ) ;
    	for ( int i = 1 ; i <= T ; ++ i ) {
    		solve () ;
    	}
    	return 0 ;
    }
    

      

    J. Math Magic

    首先我们只关心每种颜色的个数,所以有用的状态数只有$35$个,预处理出转移,然后DP即可。

    #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
    ",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
    ",S);
          //for(k=0;k<4;k++)printf("%d %d %d
    ",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
    ",ans);
      }
      return 0;
    }
    

      


    总结:

    • E题没有考虑$P=1$的情况,以后对于取模的题,在输出之前一定要取模保险。
  • 相关阅读:
    junit单元测试:@Before、@After
    package打包报错:There are test failures
    报错:程序包com.sun.image.codec.jpeg不存在
    报错:Caused by: java.sql.SQLException: Field 'id' doesn't have a default value
    elementui表格table组件的树形表格
    Linux常用命令
    黑马程序员hibernate2017版4天的讲义免费下载
    腾讯云服务器如何开放端口?
    文本编辑器中使用正则表达式进行替换的示例
    Lambda表达式
  • 原文地址:https://www.cnblogs.com/clrs97/p/6079690.html
Copyright © 2011-2022 走看看