A题
贪心思路,注意到他们每个是每个排列进行比较,因此只要判断两个字符串对应位置的大小,谁多就谁赢
#include<bits/stdc++.h> using namespace std; typedef long long ll; typedef pair<int,int> pll; const int N=5e5+10; int main(){ ios::sync_with_stdio(false); int i,j; int t; cin>>t; while(t--){ int n; cin>>n; string s; string x; cin>>s>>x; int cnt1=0,cnt2=0; for(i=0;i<n;i++){ if(s[i]>x[i]){ cnt1++; } else if(s[i]<x[i]){ cnt2++; } } if(cnt1>cnt2){ cout<<"RED"<<endl; } else if(cnt1==cnt2){ cout<<"EQUAL"<<endl; } else{ cout<<"BLUE"<<endl; } } return 0; }
B题
这道题总结出来其实就是发现我们有四个方向,最后只要有多少方案就是答案,因此就是给四个方向分配个数
只要用乘法原理就能解答
#include<bits/stdc++.h> using namespace std; typedef long long ll; typedef pair<int,int> pll; const int N=5e5+10; int main(){ ios::sync_with_stdio(false); int n; cin>>n; if(n%2==0){ cout<<(n/2+1)*(n/2+1)<<endl; } else{ cout<<2*((n-1)/2+2)*((n-1)/2+1)<<endl; } return 0; }
C题
先排序之后两两取gcd
#include<bits/stdc++.h> using namespace std; typedef long long ll; typedef pair<int,int> pll; const int N=5e5+10; ll n,m; ll ans; ll a[N],b[N]; ll gcd(ll x,ll y){ return y?gcd(y,x%y):x; } int main(){ ios::sync_with_stdio(false); cin>>n>>m; int i,j; for(i=1;i<=n;i++) cin>>a[i]; for(i=1;i<=m;i++) cin>>b[i]; sort(a+1,a+n+1); if(n>=2) ans=a[2]-a[1]; for(i=3;i<=n;i++){ ans=gcd(ans,a[i]-a[i-1]); } for(int i=1;i<=m;i++){ cout<<gcd(ans,a[1]+b[i])<<" "; } return 0; }
D题
这道题数据范围一看就是dp思路,要发现一个特征,就是因为可以一步步取水,假设我们取k个,其实相当于把其他水往k个杯子里面倒,二次转手是没有意义的
这样我们就可以设计出dp状态了f[i][j][k],表示前i个,取j个被子,容量为k的情况下的最大初始水是多少,为什么要求最大,就是因为水每倒一次就会丢一半,因此当容量固定的时候,初始水越多一定不劣
因为总水量固定,这样浪费的水一定不多于其他情况。
这一步就是背包dp,之后就是枚举所有情况取一个max,注意水量不能超过上限
#include<bits/stdc++.h> using namespace std; typedef long long ll; typedef pair<int,int> pll; const int N=2e5+10; const int mod=1e9+7; int a[N],b[N]; int f[2][110][10010]; int suma[N],sumb; int main(){ //ios::sync_with_stdio(false); int n; cin>>n; int i,j,k; for(i=1;i<=n;i++){ cin>>a[i]>>b[i]; suma[i]=suma[i-1]+a[i]; sumb+=b[i]; } int now=0; memset(f,-0x3f,sizeof f); f[0][0][0]=0; for(i=1;i<=n;i++){ now^=1; for(j=0;j<=i&&j<=n;j++){ for(k=0;k<=suma[i];k++){ f[now][j][k]=f[now^1][j][k]; } } for(j=1;j<=i&&j<=n;j++){ for(k=a[i];k<=suma[i];k++){ f[now][j][k]=max(f[now][j][k],f[now^1][j-1][k-a[i]]+b[i]); } } } int ans=0; for(i=1;i<=n;i++){ ans=0; for(k=0;k<=suma[n];k++){ ans=max(ans,min(f[now][i][k]+sumb,2*k)); } printf("%.10f ",1.0*ans/2); } cout<<endl; return 0; }