tc简要题解及代码

SRM 606 DIV1 L1

先去重,再特判一个的情况,只是他题意不是非常明白,-1和-2注意区分

SRM 606 DIV1 L2

A Linear Time Majority Vote Algorithm算法模板题,实在想不出来# TCO2016 Round 3B DIV1 L1 RemoveCharacters
把两个字母的贡献独立,并预处理
最后 O ( 2 26 ) O(2^{26}) O(226)暴扫

code

#include<bits/stdc++.h>
const int P=1e9+7;
using namespace std;
class RemoveCharacters{
    public:
    int ma[100];
    int s1[10000],s2[10000],top1,top2,flag,ans;
    void dfs(int x,int m,int an){
	if(x==26){
	    ans=max(ans,an);
	    return ;
	}
	if((ma[x]&m)==m)
	    if(ma[x]&(1<<x))
		dfs(x+1,m|(1<<x),an+1);
	dfs(x+1,m,an);
    }
    int minimalDistinct(string A, string B){
	int n=A.size(),m=B.size();
	for(int i='a';i<='z';i++)
	    for(int j='a';j<='z';j++){
		top1=top2=0;
		for(int k=1;k<=n;k++)
		    if(A[k-1]==i||A[k-1]==j)
			s1[++top1]=A[k-1];
		for(int k=1;k<=m;k++)
		    if(B[k-1]==i||B[k-1]==j)
			s2[++top2]=B[k-1];
		flag=top1==top2;
		for(int k=1;k<=top1;k++)
		    if(s1[k]!=s2[k]) flag=0;
		if(flag) ma[i-'a']|=(1<<(j-'a'));
	    }
	//for(int i=0;i<26;i++) printf("%d ",ma[i]);
	dfs(0,0,0);
	return 26-ans;
    }
};

SRM 615 Div1 L3: AlternativePiles

考虑R+1,G-1,只要 0 < = s u m < = M 0<=sum<=M 0<=sum<=M的是合法的,因为只能分M组
然后考虑 O ( n ∗ M ∗ B ) O(n*M*B) O(nMB)转移,B为去Blue的个数
然后 B m o d    2 ∗ M B \mod 2*M Bmod2M对答案不产生影响,然后复杂度为 O ( n ∗ M 2 ) O(n*M^2) O(nM2)

code

#include<bits/stdc++.h>
const int P=1e9+7;
using namespace std;
class AlternativePiles{
    public:
    int f[2][200][200];
    void work(int x,int val,int m){
	//printf("$%d %d %d\n",x,val,m);
	for(int i=0;i<=m;i++){
	    if(i+val>m) continue;
	    if(i+val<0) continue;
	    for(int j=0;j<m*2;j++)
		if(f[x^1][i][j]){
		    if(val) f[x][i+val][j]=(f[x^1][i][j]+f[x][i+val][j])%P;
		    else f[x][i][(j+1)%(m*2)]=(f[x][i][(j+1)%(m*2)]+f[x^1][i][j])%P;
		}
	}
	/*
	for(int i=0;i<=m;i++,printf("\n"))
	    for(int j=0;j<m*2;j++)
		printf("%d ",f[x][i][j]);
		*/
    }
    int count(string s,int m){
	int n=s.size();
	f[0][0][0]=1;
	for(int i=1;i<=n;i++){
	    memset(f[i&1],0,sizeof(f[i&1]));
	    if(s[i-1]=='W'){
		work(i&1,1,m);
		work(i&1,-1,m);
		work(i&1,0,m);
	    }
	    if(s[i-1]=='G') work(i&1,-1,m);
	    if(s[i-1]=='R') work(i&1,1,m);
	    if(s[i-1]=='B') work(i&1,0,m);
	}
	return f[n&1][0][n%(m*2)]%P;
    }
};

SRM 602 DIV1 L1

暴力DP既可

code

#include<bits/stdc++.h>
using namespace std;
class TypoCoderDiv1{
    public:
    int ans,f[100][10000],bo[100][10000];
    int getmax(vector <int> D, int X){
	int n=D.size(),x;
	if(n==1) return X+D[0]>=2200;
	bo[0][X]=1;
	f[0][X]=0;
	for(int i=1;i<=n;i++){
	    for(int j=0;j<2200;j++)
		if(bo[i-1][j]){
		    x=j+D[i-1];
		    if(x<=2200) f[i][x]=max(f[i][x],f[i-1][j]),bo[i][x]=1;
		    x=max(j-D[i-1],0);
		    f[i][x]=max(f[i][x],f[i-1][j]);
		    bo[i][x]=1;
		}
		/*
	    for(int j=0;j<2200;j++)
		if(bo[i][j])
		    printf("$%d ",j);
	    printf("\n");
	    */
	    fflush(stdout);
	    if(i==1) continue;
	    for(int j=0;j<2200;j++)
		if(bo[i-2][j]){
	//	    printf("$$%d %d %d %d\n",j,i,D[i-2],D[i-1]);
		    if(j+D[i-2]<2200) continue;
		    if(j+D[i-2]-D[i-1]>=2200) continue;
	//	    printf("$$$%d\n",j);
		    x=j+D[i-2]-D[i-1];
		    x=max(0,x);
		    f[i][x]=max(f[i][x],f[i-2][j]+2);
		    bo[i][x]=1;
		}
		/*
	    for(int j=0;j<2200;j++)
		if(bo[i][j])
		    printf("%d ",j);
	    printf("\n");
	    */
	}
	for(int i=0;i<2200;i++) ans=max(ans,f[n][i]);
	for(int i=0;i<2200;i++) 
	    if(bo[n-1][i]&&(D[n-1]+i>=2200))
		ans=max(ans,f[n-1][i]+1);
	return ans;
    }
};

SRM 602 DIV1 L2

所有矩形小边为X,大边为Y,那 X m i n X_{min} Xmin一定被取
那么枚举另一个X取哪一个
假设取 X i X_i Xi这种情况下要考虑i~N*2前N大给 X i X_i Xi还是后N大给 X i X_i Xi,贪心把大的给 X i X_i Xi是可以hack的,比如i~N*2的前K+1大中的最小值和次小值相同.
然后用堆维护,跑两边,分别维护两种情况

code

#include<bits/stdc++.h>
using namespace std;
long long X[600000],Y[600000],c[600000],bo[600000],minb[600000];
priority_queue<long long>q;
int mysort(int x,int y){
    return X[x]<X[y];
}
int mysort2(int x,int y){
    return Y[x]<Y[y];
}
class PilingRectsDiv1{
    public:
    long long ans;
    int len;
    long long getmax(int N, vector <int> XS, vector <int> YS, int XA, int XB, int XC, int YA, int YB, int YC){
	for (int i = 0; i < XS.size(); i++) {
	        X[i] = XS[i];
		Y[i] = YS[i];
	}
	for (int i = XS.size(); i < 2 * N; i++) {
	        X[i] = (X[i - 1] * XA + XB) % XC + 1;
		    Y[i] = (Y[i - 1] * YA + YB) % YC + 1;
	}
	for(int i=0;i<N*2;i++){
	    if(X[i]>Y[i]) swap(X[i],Y[i]);
	    c[i]=i;
	}
	sort(c,c+2*N,mysort);
	for(int i=N*2-1;i>N;i--)
	    q.push(-Y[c[i]]);
	minb[0]=Y[c[0]];
	for(int i=1;i<=N-1;i++){
	    minb[i]=min(Y[c[i]],minb[i-1]);
	}
	minb[N]=1e9+7;
	//printf("%lld",ans);
	ans=0;
	for(int i=N;i;i--){
	    q.push(-Y[c[i]]);
	    if(i!=N){
		minb[i]=min(minb[i+1],-q.top());
		q.pop();
	    }
	    ans=max(ans,1ll*(-q.top())*X[c[i]]+1ll*min(minb[i-1],minb[i])*X[c[0]]);
	}
	while(!q.empty()) q.pop();
	minb[2*N]=Y[c[2*N-1]];
	for(int i=N*2-1;i>=N;i--){
	    q.push(Y[c[i]]);
	    minb[i]=min(Y[c[i]],minb[i+1]);
	}
	minb[0]=Y[c[0]];
	for(int i=1;i<=N-1;i++){
	    minb[i]=min(Y[c[i]],minb[i-1]);
	}
	for(int i=N-1;i;i--){
	    q.push(Y[c[i]]);
	    //printf("%lld\n",minb[i+1]);
	    minb[i]=min(minb[i+1],Y[c[i]]);
	    //printf("%lld %lld %lld %lld %lld\n",q.top(),minb[i-1],X[c[0]],minb[i],X[c[i]]);
	    ans=max(ans,1ll*(min(q.top(),minb[i-1]))*X[c[0]]+1ll*minb[i]*X[c[i]]);
	    q.pop();
	}
	return ans;
    }
};

SRM 606 DIV1 L1

先去重,再特判一个的情况,只是他题意不是非常明白,-1和-2注意区分

#include<bits/stdc++.h>
using namespace std;
int a[1000],b[1000],c[1000],s[1000],top,n,an;
int mysort(int x,int y){
    return a[x]<a[y];
}
class EllysNumberGuessing{
    public:
    int getNumber(vector <int> A, vector <int> B){
	n=A.size();
	for(int i=1;i<=n;i++) a[i]=A[i-1];
	for(int i=1;i<=n;i++) b[i]=B[i-1],c[i]=i;
	sort(c+1,c+n+1,mysort);
	for(int i=1;i<=n;i++){
	    if(a[c[i]]==a[c[i-1]]){
		if(b[c[i]]!=b[c[i-1]]) return -2;
	    }else s[++top]=c[i];
	}
	int x=s[1],y=s[2];
	if(top==1){
	    if(a[x]+b[x]<=1000000000&&a[x]-b[x]>=1) return -1;
	    if(a[x]+b[x]>1000000000&&a[x]-b[x]<1) return -2;
	    if(a[x]-b[x]>=1) return a[x]-b[x];
	    return a[x]+b[x];
	}
	c[1]=a[x]-b[x];
	c[2]=a[x]+b[x];
	c[3]=a[y]-b[y];
	c[4]=a[y]+b[y];
	sort(c+1,c+5);
	for(int i=1;i<4;i++)
	    if(c[i]==c[i+1])
		an=c[i];
	if(an<1||an>1000000000) return -2;
	for(int i=1;i<=n;i++)
	    if(a[i]+b[i]!=an&&a[i]-b[i]!=an)
		return -2;
	return an;
    }
};

SRM 606 DIV1 L2

A Linear Time Majority Vote Algorithm算法模板题,实在想不出来

#include<bits/stdc++.h>
using namespace std;
class EllysPairing{
    public:
    int getMax(int M, vector<int> count, vector<int> first, vector<int> mult, vector<int> add){
	int n=count.size(),ans,sum=0,x,sum2=0;
	for(int i=0;i<n;i++){
	    x=first[i];
	    for(int j=1;j<=count[i];j++){
		//printf("%d ",x);
		if(sum==0) ans=x;
		if(ans==x) sum++;
		else sum--;
		x=(1ll*x*mult[i]+add[i])&(M-1);
	    }
	}
	//printf("\n%d %d\n",ans,sum);
	sum=0;sum2=0;
	for(int i=0;i<n;i++){
	    x=first[i];
	    sum2=sum2+count[i];
	    for(int j=1;j<=count[i];j++){
		if(ans==x) sum++;
		x=(1ll*x*mult[i]+add[i])&(M-1);
	    }
	}
	if(sum>sum2/2)
	    sum=sum2-sum;
	else sum=sum2/2;
	return sum;
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值