zoukankan      html  css  js  c++  java
  • 51nod水题记

    妈呀51nod已经刷不动了又开始跟bzoj一样总是得看题解了。。。那么发一下总结吧。。。

    1051:最大子矩阵

    #include<cstdio>
    #include<cstring>
    #include<cctype>
    #include<algorithm>
    using namespace std;
    #define rep(i,s,t) for(int i=s;i<=t;i++)
    #define dwn(i,s,t) for(int i=s;i>=t;i--)
    #define ll long long
    const int nmax=505;
    int read(){
        int x=0,f=1;char c=getchar();
        while(!isdigit(c)){
            if(c=='-') f=-1;c=getchar();
        }
        while(isdigit(c)) x=x*10+c-'0',c=getchar();
        return x*f;
    }
    ll a[nmax][nmax];
    int main(){
        int m=read(),n=read();ll ans=0,tot,tmp;
        rep(i,1,n) rep(j,1,m) a[i][j]=a[i-1][j]+read();
        rep(i,1,n) rep(j,i,n) {
            tot=0;
            rep(k,1,m) {
                tmp=tot;
                tot+=a[j][k]-a[i-1][k];
                if(tot<0) ans=max(ans,tmp),tot=0;
                ans=max(ans,tot);
            }
        }
        printf("%lld
    ",ans);
        return 0;
    }
    

    1013:等比数列求和+逆元就可以了。

    #include<cstdio>
    #include<cstring>
    #include<cctype>
    #include<algorithm>
    using namespace std;
    #define ll long long
    const ll mod=1000000007;
    int main(){
        int n;scanf("%d",&n);
        ll tmp=3,ans=1;++n;
        while(n){
            if(n&1) ans=ans*tmp%mod;
            tmp=tmp*tmp%mod;n>>=1;
        }
        printf("%lld
    ",(ans-1)*500000004%mod);
        return 0;
    }
    

    1021:石子归并O(n3)

    #include<cstdio>
    #include<cstring>
    #include<cctype>
    #include<algorithm>
    using namespace std;
    #define rep(i,s,t) for(int i=s;i<=t;i++)
    #define dwn(i,s,t) for(int i=s;i>=t;i--)
    #define clr(x,c) memset(x,c,sizeof(x))
    int read(){
    	int x=0;char c=getchar();
    	while(!isdigit(c)) c=getchar();
    	while(isdigit(c)) x=x*10+c-'0',c=getchar();
    	return x;
    }
    const int nmax=105;
    int dp[nmax][nmax],a[nmax];
    void mins(int &a,int b){
    	if(a>b) a=b;
    }
    int main(){
    	clr(dp,0x7f);
    	int n=read();rep(i,1,n) a[i]=read()+a[i-1],dp[i][i]=0;
    	rep(i,1,n-1) rep(j,1,n-i) {
    		rep(k,j,j+i-1) mins(dp[j][j+i],dp[j][k]+dp[k+1][j+i]+a[j+i]-a[j-1]);
    	}
    	printf("%d
    ",dp[1][n]);
    	return 0;
    }
    

     1268:O(2^20)爆搜。

    #include<cstdio>
    #include<cstring>
    #include<cctype>
    #include<algorithm>
    using namespace std;
    #define rep(i,s,t) for(int i=s;i<=t;i++)
    #define dwn(i,s,t) for(int i=s;i>=t;i--)
    #define clr(x,c) memset(x,c,sizeof(x))
    int a[25],n,m;
    bool dfs(int cur,int sm){
    	if(sm==m||sm+a[cur]==m) return 1;
    	if(cur>n) return 0;
    	return dfs(cur+1,sm+a[cur])||dfs(cur+1,sm);
    }
    int main(){
    	scanf("%d%d",&n,&m);
    	rep(i,1,n) scanf("%d",&a[i]);
    	if(dfs(1,0)) printf("Yes
    ");else printf("No
    ");
    	return 0;
    }
    

    1068:手推了一下发现110110110110。。。然后就可以了。。。

    #include<cstdio>
    #include<cstring>
    #include<cctype>
    #include<algorithm>
    using namespace std;
    #define rep(i,s,t) for(int i=s;i<=t;i++)
    const int nmax=1e3+5;
    char s[nmax];
    int main(){
    	int n;scanf("%d",&n);
    	rep(i,1,n) {
    		scanf("%s",s);
    		int len=strlen(s),ans=0;
    		rep(j,0,len-1) ans+=s[j]-'0';
    		ans%3?printf("A
    "):printf("B
    ");
    	}
    	return 0;
    } 

    1099:usaco做过的那种sort贪心确定顺序的题。。。

    #include<cstdio>
    #include<cstring>
    #include<cctype>
    #include<algorithm>
    using namespace std;
    #define rep(i,s,t) for(int i=s;i<=t;i++)
    #define dwn(i,s,t) for(int i=s;i>=t;i--)
    int read(){
    	int x=0;char c=getchar();
    	while(!isdigit(c)) c=getchar();
    	while(isdigit(c)) x=x*10+c-'0',c=getchar();
    	return x;
    }
    const int nmax=1e5+4;
    struct nd{
    	int x,y;
    	bool operator<(const nd&rhs)const{
    	  return x-y>rhs.x-rhs.y;}
    };
    nd ns[nmax];
    int main(){
    	int n=read();
    	rep(i,1,n) ns[i].x=read(),ns[i].y=read();
    	sort(ns+1,ns+n+1);
    	int ans=0,cur=0;
    	rep(i,1,n) ans=max(ans,cur+ns[i].x),cur+=ns[i].y;
    	printf("%d
    ",ans);
    	return 0;
    }
    

    1117:贪心每次拿最少的两个合并。

    #include<cstdio>
    #include<cstring>
    #include<cctype>
    #include<algorithm>
    #include<queue>
    using namespace std;
    #define rep(i,s,t) for(int i=s;i<=t;i++)
    #define dwn(i,s,t) for(int i=s;i>=t;i--)
    #define ll long long
    int read(){
    	int x=0;char c=getchar();
    	while(!isdigit(c)) c=getchar();
    	while(isdigit(c)) x=x*10+c-'0',c=getchar();
    	return x;
    }
    const int nmax=5e4+5;
    struct nd{
    	int x;
    	nd(int x):x(x){};
    	bool operator<(const nd&rhs) const{
    	  return x>rhs.x;}
    };
    priority_queue<nd>q;
    int main(){
    	int n=read(),u,v,ans=0;
    	rep(i,1,n) u=read(),q.push(u);
    	rep(i,1,n-1){
    		u=q.top().x;q.pop();
    		v=q.top().x;q.pop();
    		ans+=u+v;q.push(nd(u+v));
    	}
    	printf("%d
    ",ans);
    	return 0;
    }
    

    1267:4个数的和为0,n2排序一下扫一遍就可以了,sxt大爷是用map水过去的。

    #include<cstdio>
    #include<cstring>
    #include<cctype>
    #include<algorithm>
    using namespace std;
    #define rep(i,s,t) for(int i=s;i<=t;i++)
    #define dwn(i,s,t) for(int i=s;i>=t;i--)
    #define clr(x,c) memset(x,c,sizeof(x))
    int read(){
    	int x=0,f=1;char c=getchar();
    	while(!isdigit(c)){
    		if(c=='-') f=-1;c=getchar();
    	}
    	while(isdigit(c)) x=x*10+c-'0',c=getchar();
    	return x*f;
    } 
    const int nmax=1e3+5;
    const int maxn=1e6+5;
    int a[nmax];
    struct node{
    	int a,b,c;
    	bool operator<(const node&rhs) const{
    	  return c<rhs.c;}
    };
    node ns[maxn];
    int main(){
    	int n=read();
    	rep(i,1,n) a[i]=read();
    	int u=0,v,d;
    	rep(i,1,n-1) rep(j,i+1,n) ns[++u].a=i,ns[u].b=j,ns[u].c=a[i]+a[j];
    	sort(ns+1,ns+u+1);
    	int l=1,r=u;
    	while(l<=u){
    		if(!r) break;
    		if(ns[l].c+ns[r].c==0){
    			if(ns[l].a!=ns[r].a&&ns[l].a!=ns[r].b&&ns[l].b!=ns[r].a&&ns[l].b!=ns[r].b){
    				printf("Yes
    ");return 0;
    			}
    			if(ns[l].c==ns[l+1].c) ++l;
    			else if(ns[r].c==ns[r-1].c) --r;
    			else ++l,--r;
    		}else if(ns[l].c+ns[r].c<0) ++l;
    		else --r;
    	}
    	printf("No
    ");
    	return 0;
    }
    

    1163:usaco做过的贪心

    #include<cstdio>
    #include<cstring>
    #include<cctype>
    #include<algorithm>
    #include<queue>
    using namespace std;
    #define rep(i,s,t) for(int i=s;i<=t;i++)
    #define dwn(i,s,t) for(int i=s;i>=t;i--)
    #define clr(x,c) memset(x,c,sizeof(x))
    int read(){
    	int x=0;char c=getchar();
    	while(!isdigit(c)) c=getchar();
    	while(isdigit(c)) x=x*10+c-'0',c=getchar();
    	return x;
    } 
    struct node{
    	int a,b;
    	bool operator<(const node&rhs)const{
    	  return a<rhs.a;}
    };
    node ns[50005];
    struct edge{
    	int b;
    	edge(int b):b(b){};
    	bool operator<(const edge&rhs)const{
    	  return b>rhs.b;}
    };
    priority_queue<edge>q;
    int main(){
    	int n=read(),u,v,d;
    	rep(i,1,n) ns[i].a=read(),ns[i].b=read();
    	sort(ns+1,ns+n+1);
    	int cnt=0;long long ans=0;
    	rep(i,1,n){
    		if(cnt<ns[i].a) q.push(edge(ns[i].b)),++cnt,ans+=ns[i].b;
    		else if((u=q.top().b)<ns[i].b) q.pop(),q.push(edge(ns[i].b)),ans+=ns[i].b-u;
    	}
    	printf("%lld
    ",ans);
    	return 0;
    }
    

    1102:维护左边和右边能够到达的最大就可以了。

    #include<cstdio>
    #include<cstring>
    #include<cctype>
    #include<algorithm>
    using namespace std;
    #define rep(i,s,t) for(int i=s;i<=t;i++)
    #define dwn(i,s,t) for(int i=s;i>=t;i--)
    #define clr(x,c) memset(x,c,sizeof(x))
    int read(){
    	int x=0;char c=getchar();
    	while(!isdigit(c)) c=getchar();
    	while(isdigit(c)) x=x*10+c-'0',c=getchar();
    	return x;
    }
    const int nmax=5e4+5;
    int a[nmax],s[nmax],t[nmax];
    int main(){
    	int n=read();
    	rep(i,1,n) a[i]=read(),s[i]=t[i]=i;
    	rep(i,1,n) while(a[i]<=a[s[i]-1]&&s[i]>0) s[i]--;
    	dwn(i,n,1) while(a[i]<=a[t[i]+1]&&t[i]<n) t[i]++;
    	long long ans=0;
    	rep(i,1,n) ans=max(ans,(long long)(t[i]-s[i]+1)*a[i]);
    	printf("%lld
    ",ans);
    	return 0;
    }
    

    1065:用set水过去了。

    #include<cstdio>
    #include<cstring>
    #include<cctype>
    #include<algorithm>
    #include<set>
    using namespace std;
    #define rep(i,s,t) for(int i=s;i<=t;i++)
    #define dwn(i,s,t) for(int i=s;i>=t;i--)
    #define clr(x,c) memset(x,c,sizeof(x))
    #define ll long long
    ll read(){
    	ll x=0,f=1;char c=getchar();
    	while(!isdigit(c)){
    		if(c=='-') f=-1;c=getchar();
    	}
    	while(isdigit(c)) x=x*10+c-'0',c=getchar();
    	return x*f;
    }
    const int nmax=5e4+5;
    const ll inf=1e18;
    set<ll>s;
    int main(){
    	int n=read();ll cnt=0,ans=inf;
    	set<ll>::iterator it;s.insert(-inf);
    	rep(i,1,n) {
    		cnt+=read();
    		it=s.lower_bound(cnt);--it;
    		if(*it!=-inf) ans=min(ans,cnt-*it);
    		if(cnt>0) ans=min(ans,cnt);
    		s.insert(cnt);
    	}
    	printf("%lld
    ",ans);
    	return 0;
    }
    

    1270:要么选最大值要么选最小值dp就可以了。

    #include<cstdio>
    #include<cstring>
    #include<cctype>
    #include<algorithm>
    using namespace std;
    #define rep(i,s,t) for(int i=s;i<=t;i++)
    #define dwn(i,s,t) for(int i=s;i>=t;i--)
    #define clr(x,c) memset(x,c,sizeof(x))
    int read(){
    	int x=0;char c=getchar();
    	while(!isdigit(c)) c=getchar();
    	while(isdigit(c)) x=x*10+c-'0',c=getchar();
    	return x;
    }
    const int nmax=5e4+5;
    int a[nmax];
    int dp[nmax][2];
    int main(){
    	int n=read(),u,v,d,tmp,temp;
    	rep(i,1,n) a[i]=read();
    	rep(i,2,n){
    		dp[i][1]=max(dp[i-1][1]+abs(a[i-1]-a[i]),dp[i-1][0]+a[i]-1);
    		dp[i][0]=max(dp[i-1][0],dp[i-1][1]+a[i-1]-1);
    	}
    	printf("%d
    ",max(dp[n][0],dp[n][1]));
    	return 0;
    }
    

    1393:+1-1然后乱搞。。。

    #include<cstdio>
    #include<cstring>
    #include<cctype>
    #include<algorithm>
    using namespace std;
    #define rep(i,s,t) for(int i=s;i<=t;i++)
    #define dwn(i,s,t) for(int i=s;i>=t;i--)
    const int nmax=2e6+5;
    int a[nmax];char s[nmax];
    int main(){
    	scanf("%s",s+1);
    	int len=strlen(s+1),u=1e6,ans=0;
    	rep(i,1,len) {
    		if(s[i]=='0') --u;else ++u;
    		if(a[u]||u==1e6) ans=max(ans,i-a[u]);
    		else a[u]=i;
    	}
    	printf("%d
    ",ans);
    	return 0;
    }
    

    1127:线性扫一下就可以了。。。r是递增的

    #include<cstdio>
    #include<cstring>
    #include<cctype>
    #include<algorithm>
    using namespace std;
    #define rep(i,s,t) for(int i=s;i<=t;i++)
    #define dwn(i,s,t) for(int i=s;i>=t;i--)
    #define clr(x,c) memset(x,c,sizeof(x))
    const int nmax=1e5+5;
    const int inf=0x7f7f7f7f;
    char s[nmax];
    int a[30];
    int main(){
    	scanf("%s",s+1);
    	int r=0,n=strlen(s+1),cnt=0,ans=inf;
    	rep(i,1,n){
    		if(i!=1&&!--a[s[i-1]-'A']) --cnt;
    		while(cnt<26&&r<n){
    			if(++a[s[++r]-'A']==1) ++cnt;
    		}
    		if(cnt!=26) break;
    		ans=min(ans,r-i+1);
    	}
    	if(ans==inf) printf("No Solution
    ");
    	else printf("%d
    ",ans);
    	return 0;
    }
    

    1097:我只会用string水过去。。。好像usaco做过类似的题。

    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    using namespace std;
    #define rep(i,s,t) for(int i=s;i<=t;i++)
    #define dwn(i,s,t) for(int i=s;i>=t;i--)
    int read(){
    	int x=0;char c=getchar();
    	while(!isdigit(c)) c=getchar();
    	while(isdigit(c)) x=x*10+c-'0',c=getchar();
    	return x;
    }
    const int nmax=1e4+5;
    struct node{
    	string s;
    	bool operator<(const node&rhs)const {
    	  return s+rhs.s<rhs.s+s;}
    };
    node a[nmax];
    int main(){
    	int n=read();
    	rep(i,1,n) cin>>a[i].s;
    	sort(a+1,a+n+1);
    	string ans=a[1].s;
    	rep(i,2,n) ans=ans+a[i].s;
    	rep(i,0,ans.size()-1){
    		cout<<ans[i];
    		if((!((i+1)%1000))) printf("
    ");
    	}
    	if(ans.size()%1000) printf("
    ");
    	return 0;
    }
    

    1272:sort一下乱搞就可以了。。。标签是单调栈然后死想想不出来。。。

    #include<cstdio>
    #include<cstring>
    #include<cctype>
    #include<algorithm>
    using namespace std;
    #define rep(i,s,t) for(int i=s;i<=t;i++)
    #define dwn(i,s,t) for(int i=s;i>=t;i--)
    #define clr(x,c) memset(x,c,sizeof(x))
    int read(){
    	int x=0;char c=getchar();
    	while(!isdigit(c)) c=getchar();
    	while(isdigit(c)) x=x*10+c-'0',c=getchar();
    	return x;
    }
    const int nmax=5e4+5;
    struct node{
    	int a,b;
    	bool operator<(const node&rhs)const {
    	  return a<rhs.a||a==rhs.a&&b<rhs.b;}
    };
    node ns[nmax];
    int main(){
    	int n=read();
    	rep(i,1,n) ns[i].a=read(),ns[i].b=i;
    	sort(ns+1,ns+n+1);
    	int u=ns[1].b,ans=0;
    	rep(i,2,n){
    		if(ns[i].b>u) ans=max(ans,ns[i].b-u);
    		else u=ns[i].b;
    	}
    	printf("%d
    ",ans);
    	return 0;
    }
    

    1116:用到的性质不会证明不然的话就是也挺好写的。

    //n*k%k-1=n%k-1*k%k-1=n%k-1;
    #include<cstdio>
    #include<cstring>
    #include<cctype>
    #include<algorithm>
    using namespace std;
    #define rep(i,s,t) for(int i=s;i<=t;i++)
    #define dwn(i,s,t) for(int i=s;i>=t;i--)
    const int nmax=1e5+5;
    char s[nmax];
    int main(){
    	scanf("%s",s+1);
    	int len=strlen(s+1),ans=0,mx=0,tmp;
    	rep(i,1,len){
    		if(s[i]>='0'&&s[i]<='9') mx=max(mx,tmp=s[i]-'0');
    		else mx=max(mx,tmp=s[i]-'A'+10);
    		ans+=tmp;
    	}
    	rep(i,mx+1,36) if(ans%(i-1)==0) {
    		printf("%d
    ",i);return 0;
    	}
    	printf("No Solution
    ");
    	return 0;
    }
    

    1770:总是WA了一个点过不了似乎是因为n-2并不是所有情况都一样!?! 而且我这样子写只适合于n<100的情况把。 

    /*#include<cstdio>
    #include<cstring>
    #include<cctype>
    #include<algorithm>
    using namespace std;
    #define rep(i,s,t) for(int i=s;i<=t;i++)
    #define dwn(i,s,t) for(int i=s;i>=t;i--)
    #define clr(x,c) memset(x,c,sizeof(x))
    int read(){
    	int x=0;char c=getchar();
    	while(!isdigit(c)) c=getchar();
    	while(isdigit(c)) x=x*10+c-'0',c=getchar();
    	return x;
    }
    int cnt[11];
    int main(){
    	int t=read();
    	while(t--){
    		int a=read(),b=read(),d=read(),n=read();
    		int u=a*b/10,v=a*b%10;
    		if(u+v<=9) {
    			if(!u){
    				if(d==v) printf("%d
    ",n);
    				else printf("0
    ");
    			}else{
    				clr(cnt,0);
    				cnt[u]++;cnt[v]++;if(n>1) cnt[u+v]+=n-1;
    				printf("%d
    ",cnt[d]);
    			}
    		}else{
    			clr(cnt,0);
    			cnt[v]++;cnt[(u+v)%10]++;if(n>2) cnt[(u+v)%10+1]+=n-2;cnt[u+1]++;
    			printf("%d
    ",cnt[d]);
    		}
    	}
    	return 0;
    }*/
     #include<cstdio>
    #include<cstring>
    #include<cctype>
    #include<algorithm>
    using namespace std;
    #define rep(i,s,t) for(int i=s;i<=t;i++)
    #define dwn(i,s,t) for(int i=s;i>=t;i--)
    #define clr(x,c) memset(x,c,sizeof(x))
    int read(){
    	int x=0;char c=getchar();
    	while(!isdigit(c)) c=getchar();
    	while(isdigit(c)) x=x*10+c-'0',c=getchar();
    	return x;
    }
    int main(){
    	int T=read();
    	while(T--){
    		int a=read(),b=read(),d=read(),n=read();
    		int ans=0,u=0,v=0,pre=-1,tmp;
    		rep(i,1,n){
    			tmp=a*b+v;v=tmp/10;u=tmp%10;
    			if(tmp==pre){
    				if(u==d) ans+=n-i+1;
    				break;
    			}
    			pre=tmp;
    			if(u==d) ans++;
    		}
    		if(v&&v==d) ans++;
    		printf("%d
    ",ans);
    	}
    	return 0;
    }
    

    1179:这道题很明显是利用s[i]的范围来搞,时间复杂度是O(mxlnmx)差不多2000w的复杂度。

    #include<cstdio>
    #include<cstring>
    #include<cctype>
    #include<algorithm>
    using namespace std;
    #define rep(i,s,t) for(int i=s;i<=t;i++)
    #define dwn(i,s,t) for(int i=s;i>=t;i--)
    #define clr(x,c) memset(x,c,sizeof(x))
    int read(){
    	int x=0;char c=getchar();
    	while(!isdigit(c)) c=getchar();
    	while(isdigit(c)) x=x*10+c-'0',c=getchar();
    	return x;
    }
    const int nmax=1e6+5;
    int a[nmax];
    int main(){
    	int n=read(),u,v,d,mx=0;
    	rep(i,1,n) a[u=read()]++,mx=max(mx,u);
    	dwn(i,mx,1){
    		if(a[i]>=2) {
    			printf("%d
    ",i);return 0;
    		}
    		d=a[i];
    		for(int j=i+i;j<=mx;j+=i){
    			if((d+=a[j])>=2){
    				printf("%d
    ",i);return 0;
    			}
    		}
    	}
    	return 0;
    }
    

    1070:斐波那契博弈。然而我看不懂证明。。。

    #include<cstdio>
    #include<cstring>
    #include<cctype>
    #include<algorithm>
    using namespace std;
    #define rep(i,s,t) for(int i=s;i<=t;i++)
    #define dwn(i,s,t) for(int i=s;i>=t;i--)
    #define clr(x,c) memset(x,c,sizeof(x))
    int read(){
    	int x=0;char c=getchar();
    	while(!isdigit(c)) c=getchar();
    	while(isdigit(c)) x=x*10+c-'0',c=getchar();
    	return x;
    }
    const int nmax=50;
    int a[nmax];
    int main(){
    	a[0]=1;a[1]=1;
    	rep(i,1,43) a[i]=a[i-1]+a[i-2];
    	int t=read();
    	while(t--){
    		int n=read(),f=-1;
    		rep(i,1,45){
    			if(a[i]==n){
    				f=1;printf("B
    ");break;
    			}
    		}
    		if(f<0) printf("A
    ");
    	}
    	return 0;
    }
    

    1491:神题。。我只知道他是斐波那契数列然后就不会了。。。

    #include<cstdio>
    #include<cstring>
    #include<cctype>
    #include<algorithm>
    #include<cmath>
    using namespace std;
    #define rep(i,s,t) for(int i=s;i<=t;i++)
    #define dwn(i,s,t) for(int i=s;i>=t;i--)
    const int nmax=1e5+5;
    char a[nmax],b[nmax];
    int f[nmax];
    int main(){
    	scanf("%s%s",a+1,b+1);
    	int lena=strlen(a+1),lenb=strlen(b+1),len=max(lena,lenb);
    	rep(i,1,lena) f[lena-i]=a[i]-'0';
    	rep(i,1,lenb) f[lenb-i]+='0'-b[i];
    	dwn(i,len,2) {
    		if(f[i]<-1) {
    			printf("<
    ");return 0;
    		}else if(f[i]>1){
    			printf(">
    ");return 0;
    		}
    		f[i-1]+=f[i];f[i-2]+=f[i];
    	}
    	f[1]+=f[2];f[0]+=f[2];
    	if(f[1]==0&&f[0]==0) {
    		printf("=
    ");return 0;
    	}
    	double u=(sqrt(5)+1)/2,ans=f[1]*u+f[0];
    	if(ans>0) printf(">
    ");else printf("<
    ");
    	return 0;
    }
    

    1605:奇偶判断一下就好了。。。好像以前做过相似的。

    #include<cstdio>
    #include<cstring>
    #include<cctype>
    #include<algorithm>
    using namespace std;
    #define rep(i,s,t) for(int i=s;i<=t;i++)
    #define dwn(i,s,t) for(int i=s;i>=t;i--)
    int main(){
    	int T;scanf("%d",&T);
    	while(T--){
    		int n,m,u,cnt=0;scanf("%d%d",&n,&m);
    		rep(i,1,n) rep(j,1,m) scanf("%d",&u),cnt+=u;
    		if(cnt%2) printf("yadang
    ");
    		else printf("xiawa
    ");
    	}
    	return 0;
    }
    

    1412:很明显是利用树的深度来dp因为数据范围那样我能想到的只是这个了。。。

    #include<cstdio>
    #include<cstring>
    #include<cctype>
    #include<algorithm>
    using namespace std;
    #define rep(i,s,t) for(int i=s;i<=t;i++)
    #define dwn(i,s,t) for(int i=s;i>=t;i--)
    #define clr(x,c) memset(x,c,sizeof(x))
    #define ll long long
    const ll mod=1e9+7;
    ll dp[2005][16];
    int main(){
    	int n;scanf("%d",&n);
    	dp[0][0]=dp[1][1]=1;
    	rep(i,2,n) rep(j,2,15) rep(k,0,i-1) {
    		(dp[i][j]+=dp[k][j-1]*dp[i-1-k][j-1])%=mod;
    		(dp[i][j]+=2*dp[k][j-2]*dp[i-1-k][j-1])%=mod;
    	}
    	ll ans=0;
    	rep(i,1,15) (ans+=dp[n][i])%=mod;
    	printf("%lld
    ",ans);
    	return 0;
    }
    

    1020:bzoj写过的神dp。。dp一个见过的优化技巧就是省掉一维!!!

    #include<cstdio>
    #include<cstring>
    #include<cctype>
    #include<algorithm>
    using namespace std;
    #define rep(i,s,t) for(int i=s;i<=t;i++)
    #define dwn(i,s,t) for(int i=s;i>=t;i--)
    #define clr(x,c) memset(x,c,sizeof(x))
    #define ll long long
    int read(){
    	int x=0;char c=getchar();
    	while(!isdigit(c)) c=getchar();
    	while(isdigit(c)) x=x*10+c-'0',c=getchar();
    	return x;
    }
    const int nmax=2e4+5;
    const int mod=1e9+7;
    int dp[1005][nmax];
    int main(){
    	rep(i,1,1000) dp[i][0]=1;
    	rep(i,2,1000) {
    		rep(j,1,min(i*(i-1)/2,20000)) {
    			dp[i][j]=((ll)dp[i][j-1]+dp[i-1][j])%mod;
    			if(j-i>=0) dp[i][j]=((ll)dp[i][j]-dp[i-1][j-i]+mod)%mod;
    		}
    	}
    	int t=read();
    	while(t--){
    		int n=read(),k=read();
    		printf("%d
    ",dp[n][k]);
    	}
    	return 0;
    }
    

    1405:树形dp先求出size和子树节点的距离之和,再推出其他的节点到他的距离之和即可。好像写过啊qaq。。 

    #include<cstdio>
    #include<cstring>
    #include<cctype>
    #include<algorithm>
    using namespace std;
    #define rep(i,s,t) for(int i=s;i<=t;i++)
    #define qwq(x) for(edge *o=head[x];o;o=o->next)
    #define ll long long
    int read(){
    	int x=0;char c=getchar();
    	while(!isdigit(c)) c=getchar();
    	while(isdigit(c)) x=x*10+c-'0',c=getchar();
    	return x;
    }
    const int nmax=1e5+5;
    const int inf=0x7f7f7f7f;
    struct edge{
    	int to;edge *next;
    };
    edge es[nmax<<1],*pt=es,*head[nmax];
    void add(int u,int v){
    	pt->to=v;pt->next=head[u];head[u]=pt++;
    	pt->to=u;pt->next=head[v];head[v]=pt++;
    }
    int size[nmax],n;
    ll f[nmax],g[nmax];
    void dfs(int x,int fa){
    	size[x]=1;
    	qwq(x) if(o->to!=fa) {
    		dfs(o->to,x);size[x]+=size[o->to];f[x]+=f[o->to]+size[o->to];
    	}
    }
    void DFS(int x,int fa){
    	qwq(x) if(o->to!=fa){
    		g[o->to]=g[x]+n-size[x]+f[x]-f[o->to]-size[o->to]+size[x]-size[o->to];
    		DFS(o->to,x);
    	}
    }
    int main(){
    	n=read();int u,v,d;
    	rep(i,1,n-1) u=read(),v=read(),add(u,v);
    	dfs(1,0);DFS(1,0);
    	rep(i,1,n) printf("%lld
    ",f[i]+g[i]);
    	return 0;
    }
    

    1105:看数据范围明显是nlogn的做法。二分一下。挺好想的一道题。

    #include<cstdio>
    #include<cstring>
    #include<cctype>
    #include<algorithm>
    using namespace std;
    #define rep(i,s,t) for(int i=s;i<=t;i++)
    #define dwn(i,s,t) for(int i=s;i>=t;i--)
    #define clr(x,c) memset(x,c,sizeof(x))
    #define ll long long
    ll read(){
    	ll x=0;char c=getchar();
    	while(!isdigit(c)) c=getchar();
    	while(isdigit(c)) x=x*10+c-'0',c=getchar();
    	return x;
    }
    const int nmax=5e4+5;
    ll a[nmax],b[nmax],n,K;
    ll check(ll x){
    	ll sm=0,tp;
    	dwn(i,n,1){
    		tp=lower_bound(b+1,b+n+1,(x-1)/a[i]+1)-b;
    		sm+=n-tp+1;
    		if(tp==n+1) break;
    	}
    	return sm;
    }
    int main(){
    	n=read(),K=read();
    	rep(i,1,n) a[i]=read(),b[i]=read();
    	sort(a+1,a+n+1);sort(b+1,b+n+1);
    	ll l=a[1]*b[1],r=a[n]*b[n],mid,ans;
    	while(l<=r){
    		mid=(l+r)>>1;
    		if(check(mid)>=K) ans=mid,l=mid+1;
    		else r=mid-1;
    	}
    	printf("%lld
    ",ans);
    	return 0;
    }
    

    1103:容斥原理。

    #include<cstdio>
    #include<cstring>
    #include<cctype>
    #include<algorithm>
    using namespace std;
    #define rep(i,s,t) for(int i=s;i<=t;i++)
    #define dwn(i,s,t) for(int i=s;i>=t;i--)
    #define clr(x,c) memset(x,c,sizeof(x))
    int read(){
    	int x=0;char c=getchar();
    	while(!isdigit(c)) c=getchar();
    	while(isdigit(c)) x=x*10+c-'0',c=getchar();
    	return x;
    }
    const int nmax=5e4+5;
    int a[nmax],b[nmax];
    int main(){
    	int n=read(),flag=0,u,sm=0;
    	rep(i,1,n){
    		a[i]=read();sm=(sm+a[i])%n;
    		if(flag) continue;
    		if(!sm){
    			printf("%d
    ",i);
    			rep(j,1,i) printf("%d
    ",a[j]);
    			flag=1;
    		}
    		else if(!b[sm]) b[sm]=i;
    		else{
    			int tp=b[sm];
    			printf("%d
    ",i-tp);
    			rep(j,tp+1,i) printf("%d
    ",a[j]);
    			flag=1;
    		}
    	}
    	return 0;
    }
    

    1040:欧拉函数。。。

    //gcd(i,n)=x gcd(i/x,n/x)=1 phi(n/x)*x;
    #include<cstdio>
    #include<cstring>
    #include<cctype>
    #include<algorithm>
    using namespace std;
    #define rep(i,s,t) for(int i=s;i<=t;i++)
    #define dwn(i,s,t) for(int i=s;i>=t;i--)
    #define clr(x,c) memset(x,c,sizeof(x))
    #define ll long long
    ll get(ll x){
        ll ans=x;
        for(ll i=2;i*i<=x;i++){
            if(x%i==0) ans=ans/i*(i-1);
            while(x%i==0) x/=i;
        }
        if(x!=1) ans=ans/x*(x-1);
        return ans;
    }
    int main(){
    	ll n;scanf("%lld",&n);
    	long long ans=0;
    	for(ll i=1;i*i<=n;i++){
    		if(n%i) continue;
    		ans+=i*get(n/i);
    		if(i*i!=n) ans+=(n/i)*get(i);
    	}
    	printf("%lld
    ",ans);
    	return 0;
    }
    

    ❤1632:线性求逆元然后递推出组合数。然而我真心看不懂题意的转化。。。

    //c(n-1,m)=(n-1)!/m!(n-1-m)! c(n-1,m-1)=(n-1)!/(m-1)!(n-1-m+1)! c(n-1,m)=c(n-1,m-1)*inv[m]*(n-m)
    #include<cstdio>
    #include<cstring>
    #include<cctype>
    #include<algorithm>
    using namespace std;
    #define rep(i,s,t) for(int i=s;i<=t;i++)
    #define dwn(i,s,t) for(int i=s;i>=t;i--)
    #define clr(x,c) memset(x,c,sizeof(x))
    #define qwq(x) for(edge *o=head[x];o;o=o->next)
    #define ll long long
    int read(){
    	int x=0;char c=getchar();
    	while(!isdigit(c)) c=getchar();
    	while(isdigit(c)) x=x*10+c-'0',c=getchar();
    	return x;
    }
    const int nmax=1e5+5;
    const ll mod=1e9+7;
    ll inv[nmax];
    int main(){
    	int n=read(),u,v;
    	rep(i,1,n-1) u=read(),v=read();
    	inv[1]=1;
    	rep(i,2,n) inv[i]=(mod-mod/i)*inv[mod%i]%mod;
    	ll ans=1,tmp=1;
    	rep(i,1,n-1){
    		tmp=tmp*(n-i)%mod*inv[i]%mod;
    		ans=(ans+tmp*(i+1)%mod)%mod;
    	}
    	printf("%lld
    ",ans);
    	return 0;
    }
    

    1419:推规律。

    #include<cstdio>
    #define ll long long
    int main(){
    	ll n;scanf("%lld",&n);
    	if(n<=2) printf("%d
    ",n);
    	else if(n&1) printf("%lld
    ",n*(n-1)*(n-2));
    	else if(n%3) printf("%lld
    ",n*(n-1)*(n-3));
    	else printf("%lld
    ",(n-1)*(n-2)*(n-3));
    	return 0;
    }
    

      

  • 相关阅读:
    初学angular
    C#二维数组及其本质(转)
    蓝桥杯之递归算法
    同时安装Office2016和Visio2016
    蓝桥杯之暴力破解、枚举
    NAT(地址解析协议)
    云中继
    ACL(访问控制列表)
    虚拟链路(virtual-link)
    单臂路由
  • 原文地址:https://www.cnblogs.com/fighting-to-the-end/p/5857965.html
Copyright © 2011-2022 走看看