您的位置:首页 > 其它

Codeforces Round #243(div.2)

2014-05-02 16:40 423 查看
A

找出最大的一个,然后其他的数字的和不大于杯子容量就可以了。代码如下:

#include<iostream>
using namespace std;
int main(){
    int sum=0;
    int maxn=-1;
    int n,s;
    cin>>n>>s;
    for(int i=0;i<n;++i){
        int v;
        cin>>v;
        sum+=v;
        if(v>maxn)maxn=v;
    }
    sum-=maxn;
    if(sum<=s)cout<<"YES"<<endl;
    else cout<<"NO"<<endl;
    return 0;
}


B

大意是把一个矩阵的一部分最少投影几次可以得到这个矩阵。暴力就可以。前两次提交一次忘记了判断ans小于n,一次忘记了在symmetry函数里面把s乘2,导致re。代码如下:

#include<iostream>
using namespace std;

int matr[110][110];
int m,n;

int symmetry(int s){
    int tmp=s;
    while(s<n){
        for(int i=1;i<=s;++i){
            for(int t=1;t<=m;++t){
                if(matr[i][t]==matr[2*s-(i-1)][t]){continue;}
                else return false;
            }
        }
        s*=2;
    }
    return true;
}

int main(){
//  freopen("data.txt","r",stdin);
    ios::sync_with_stdio(false);
    
    cin>>n>>m;
    for(int i=1;i<=n;++i){
        for(int t=1;t<=m;++t){
            cin>>matr[i][t];
        }
    }
    if(n%2){cout<<n<<endl;return 0;}
    int ans=n/2;
    int tmp=n;
    while(!(tmp%2)&&tmp){
        tmp/=2;
    }
    ans=tmp;
    while(!symmetry(ans)&&ans<n){
        ans*=2;
    }
    cout<<ans<<endl;
    return 0;
}


C

暴力出每个区间,然后将区间里面的元素进行交换,找打最大解即可。不要把简单的问题想复杂了,这是我犯的一个错误

D

题目的意思没怎么看懂,后来看别人的题解隐隐约约理解了……不过还是不算太懂。就是知道两行的数字要么完全一样,要么完全不一样。

分两类情况,第一类是k小于n的时候,必然有一些行的数字不能改动,就直接暴力每一行就可以。如果k大于n,那么n小于等于10,这时枚举一行的所有情况,最多1024种情况。代码如下:

#include<iostream>
using namespace std;

int mat[105][105];
int n,m,k;

int n_t(){
    int ans=20000;
    for(int i=0;i<n;++i){
        int tmp=0;
        for(int t=0;t<n;++t){
            int rec1=0;
            int rec2=0;
            for(int k=0;k<m;++k){
                if(mat[i][k]!=mat[t][k])rec1++;
                if(mat[i][k]==mat[t][k])rec2++;
            }
            tmp+=min(rec1,rec2);
        }
        ans=min(ans,tmp);
    }
    return ans;
}

int t_n(){
    int pos=(1<<n);
    int ans=20000;
    for(int i=0;i<pos;++i){
        int tmp=0;
        for(int t=0;t<m;++t){
            int rec1=0;
            int rec2=0;
            for(int j=0;j<n;++j){
                int rec=i&(1<<j);
                if(rec==(mat[j][t]<<j))rec1++;
                else rec2++;
            }
            if(rec1+rec2!=n){cout<<"false"<<endl;return 0;}
            tmp+=min(rec1,rec2);
        }
        ans=min(ans,tmp);
    }
    return ans;
}

int main(){
//  freopen("data.txt","r",stdin);
    cin>>n>>m>>k;
    for(int i=0;i<n;++i){
        for(int t=0;t<m;++t){
            cin>>mat[i][t];
        }
    }
//  cout<<n<<' '<<m<<' '<<k<<endl;
    int ans=20000;
    if(n>k){
        ans=n_t();
    }
    if(k>=n){
        ans=t_n();
    }
//  cout<<ans<<endl;
    if(ans>k)cout<<-1<<endl;
    else cout<<ans<<endl;
    return 0;
}


E

dp[i,j]表示第i次删除,a数组中小于等于j的位置时,在b数组中最小的位置。状态转移方程是dp[i,j]=min(dp[i,j],pos),pos即为a[j]在b数组中满足的最小的位置。用容器保存b每一个元素的位置,然后直接在里面查找就可以了。用二分找出dp[i-1,j-1]位置以后的符合要求的位置。

代码如下:

#include<iostream>
#include<vector>
#include<algorithm>
#include<cstring>
using namespace std;

int dp[305][100005];
int a[100005];
int b[100005];
vector<int> g[100005];

int main(){
//	freopen("data.txt","r",stdin);
	ios::sync_with_stdio(false);
	int n,m,s,e;
	cin>>n>>m>>s>>e;
	for(int i=1;i<=n;++i){
		cin>>a[i];
	}
	for(int i=1;i<=m;++i){
		cin>>b[i];
		g[b[i]].push_back(i);
	}
	for(int i=0;i<100001;++i){
		g[i].push_back(1000010);
	}
	int k=s/e;
	for(int i=0;i<305;++i){
		for(int t=0;t<100005;++t){
			dp[i][t]=100000000;
		}
	}
//	memset(dp,10000000,sizeof(dp));
//	cout<<"cp"<<' '<<dp[0][0]<<endl;
	memset(dp[0],0,sizeof(dp[0]));
	for(int i=1;i<=k;++i){
		for(int t=1;t<=n;++t){
			if(dp[i-1][t-1]<=100000){
				dp[i][t]=dp[i][t-1];
				int pos=*lower_bound(g[a[t]].begin(),g[a[t]].end(),dp[i-1][t-1]+1);
	//			cout<<dp[i][t-1]<<' '<<pos<<endl;
				dp[i][t]=min(dp[i][t],pos);
			}
		}
	}
	int ans=0;
	for(int i=1;i<=k;++i){
		for(int t=1;t<=n;++t){
//			cout<<dp[i][t]<<' ';
			if(dp[i][t]<100001&&((t+dp[i][t])+i*e<=s)){
				ans=max(ans,i);
			}
		}
//		cout<<endl;
	}
	cout<<ans<<endl;
	return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: