• 7.24 第四次多校


    1001_hdu5763
    听说有人没用kmp直接平方过了(摔)

    /*令dp[i]表示到i结尾的字符串可以表示的不同含义数,那么考虑两种转移:
    末尾不替换含义:dp[i - 1]
    末尾替换含义:dp[i - |B|]  (A.substr(i - |B| + 1,|B|) = B)
    那么对于末尾替换含义的转移,需要快速判断BB能不能和当前位置的后缀匹配,kmp或者hash判断即可。
    复杂度:O(N)*/ 
    //cww97
    #include<cstdio>
    #include<cstring>
    using namespace std;
    typedef long long ll;
    const int N=100007;
    const int P=1000000007;
    char a[N],b[N];
    bool mat[N];
    int next[N];
    ll f[N];
    
    void getNext(int m){
    	int i=0,j=-1;
    	next[0]=-1;
    	while (i<m){
    		if (j==-1||b[i]==b[j]){
    			if (b[++i]!=b[++j])next[i]=j;
    			else next[i]=next[j];
    		}else j=next[j];
    	}
    }
    
    void KMP(int n,int m){
    	memset(mat,0,sizeof(mat));
    	int i=0,j=0;
    	getNext(m);
    	while (i<n&&j<m){
    		if (j==-1||a[i]==b[j])i++,j++;
    		else j=next[j];
    		if (!i&&!j)break;
    		if (j==m){
    			mat[i]=1;
    			//printf("mat[%d]get
    ",i);
    			j=next[j];
    		}
    	}
    }
    
    int main(){
    	//freopen("fuck.in","r",stdin);
    	int T;
    	scanf("%d
    ",&T);
    	for (int cas=1;cas<=T;cas++){
    		scanf("%s%s",a,b);
    		int n=strlen(a);
    		int m=strlen(b);
    		KMP(n,m);
    		memset(f,0,sizeof(f));
    		f[0]=1;
    		for (int i=1;i<=n+1;i++){
    			if (mat[i])f[i]=(f[i-m]+f[i-1])%P;
    			else f[i]=(f[i-1])%P;
    			//printf("f[%d]=%d
    ",i,f[i]);
    		}
    		printf("Case #%d: %I64d
    ",cas,f[n]%P);
    	}
    	return 0;
    }
    

    1010_hdu5773
    复制下cw的讲解:
    很巧妙的智商题。意思是数列里的 0 可以替换成任何数。做法很巧妙,如果 a1 ai 中有 z 个 0 的话,就把 ai 当作 ai − z 处理。遇到 0 不处理,最后把答案数加上总的 0 的个数即可

    #include<cstdio>
    using namespace std;
    const int N=1000010;
    int s[N],top,num;
    
    int Find(int x){
    	int l=1,r=top;
    	while (l<r){
    		int mid=(l+r)>>1;
    		if (s[mid]<=x)l=mid+1;
    		else r=mid;
    	}
    	return l;
    }
    
    int main(){
    	int T,n,x;
    	scanf("%d",&T);
    	for (int cas=1;cas<=T;cas++){
    		scanf("%d",&n);
    		num=0,top=0;
    		s[0]=-100000007;
    		for (;n--;){
    			scanf("%d",&x);
    			if (!x)num++;
    			else {
    				x-=num;
    				if (x>s[top]) s[++top]=x;
    				else s[Find(x)]=x;
    			}
    		}
    		printf("Case #%d: %d
    ",cas,top+num);
    	}
    	return 0;
    } 
    

    1011
    第一次见吧

    #include<cstdio>
    #include<map>
    #include<string>
    #include<iostream>
    using namespace std;
    map<string,int>mp;
    int a[100];
    
    int main(){
    	//freopen("fuck.in","r",stdin);
    	mp["Cleveland Cavaliers"]=0; a[0]=1;
    	mp["San Antonio Spurs"]=1;   a[1]=5;
    	mp["Miami Heat"]=2;          a[2]=3;
    	mp["Dallas Mavericks"]=3;    a[3]=1;
    	mp["L.A. Lakers"]=4;         a[4]=11;
    	mp["Boston Celtics"]=5;      a[5]=17;
    	mp["Detroit Pistons"]=7;     a[7]=3;
    	mp["Chicago Bulls"]=8;       a[8]=6;
    	mp["Houston Rockets"]=9;     a[9]=2;
    	mp["Philadelphia 76ers"]=10; a[10]=2;
    	mp["Seattle Sonics"]=11;     a[11]=1;
    	mp["Washington Bullets"]=12; a[12]=1;
    	mp["Portland Trail Blazers"]=13;a[13]=1;
    	mp["Golden State Warriors"]=14;a[14]=2;
    	mp["New York Knicks"]=15;    a[15]=2;
    	mp["Milwaukee Bucks"]=16;    a[16]=1;
    	mp["St. Louis Hawks"]=17;    a[17]=1;
    	mp["Philadelphia Warriors"]=18;a[18]=2;
    	mp["Syracuse Nats"]=19;      a[19]=1;
    	mp["Minneapolis Lakers"]=20; a[20]=5;
    	mp["Rochester Royals"]=21;   a[21]=1;
    	mp["Baltimore Bullets"]=22;  a[22]=1;
    	
    	int T,ans;
    	string st;
    	scanf("%d
    ",&T);
    	for (int cas=1;cas<=T;cas++){
    		getline(cin,st);
    		if (mp.find(st)==mp.end())ans=0;
    		else ans=a[mp[st]];
    		printf("Case #%d: %d
    ",cas,ans);
    	}
    	return 0;
    } 
    

    1012

    一开始跟队友同时交了一发abs(a[i]-i),,,T_T
    树状数组维护逆序对
    cw的讲解:
    问在冒泡排序中,每个数可能出现的最左位置和最右位置之差。最多往右移动次数其实就是这个数在当前位置时右边有多少个比它小的个数,这个倒过来做一遍即可,用树状数组维护。接着再排序一遍,在初始位置,最右位置,排序后的位置中分别找出最左和最右,然后算出答案。

    #include<cstdio> 
    #include<cmath>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    const int N=100010; 
    int a[N],c[N],l[N],r[N];
    int n;
    
    int sum(int x){
    	int s=0;
    	for (;x;x-=x&-x) s+=c[x];
    	return s;
    }
    
    void add(int x){
    	for (;x<=n;x+=x&-x) c[x]++;
    }
    
    int main(){
    	//freopen("fuck.in","r",stdin);
    	int T,x;
    	scanf("%d",&T);
    	for (int cas=1;cas<=T;cas++){
    		memset(c,0,sizeof(c));
    		scanf("%d",&n);
    		for (int i=1;i<=n;i++){
    			scanf("%d",&a[i]);
    			l[a[i]]=i;
    		}
    		for (int i=n;i;i--){
    			r[a[i]]=l[a[i]]+sum(a[i]-1);
    			add(a[i]);
    			l[a[i]]=min(a[i],i);
    			//printf("%d,l=%d,r=%d
    ",a[i],l[a[i]],r[a[i]]);
    		}
    		printf("Case #%d:",cas);
    		for (int i=1;i<=n;i++) {
    			printf(" %d",r[i]-l[i]);
    		}
    		puts("");
    	}
    	return 0;
    }
    
  • 相关阅读:
    1094 纪念品分组
    1803 凌乱的yyy
    1181 数列分段1
    1223排队接水
    1616 疯狂的采药(完全背包问题)
    1305 新二叉树
    1280 尼克的任务
    1020 导弹拦截
    快速学会如何使用Shiro
    mysql 让清空表且自增的id重新从0开始的命令
  • 原文地址:https://www.cnblogs.com/cww97/p/12349396.html
Copyright © 2020-2023  润新知