Educational Codeforces Round 21 A-E題題解
A題 ............太水就不說了,貼下代碼
#include<string> #include<iostream> #include<cstring> #include<cmath> #include<algorithm> #include<vector> #include<queue> #include<cstdio> using namespace std; int n,m; int main() { int i,j; scanf("%d",&n);int nn=n; int cnt=1; while(nn>=10) { nn/=10; cnt*=10; } printf("%d\n",cnt*(nn+1)-n); }
B題 開始沒看懂題什麽意思(英語渣),然後看著樣例找到了規律,就AC了
題意是計算上升和下降的序列數之和,再除以n-k+1即可,相當於求其中每k個數的和的平均值!
#include<string> #include<iostream> #include<cstring> #include<cmath> #include<algorithm> #include<vector> #include<queue> #include<cstdio> using namespace std; int n,m,k; double arr[200005]; double sum[200005]; int main() { int i,j; scanf("%d%d",&n,&k); for(i=1;i<=n;i++)scanf("%lf",&arr[i]); sum[0]=0; for(i=1;i<=n;i++)sum[i]=sum[i-1]+arr[i]; double ans=0; for(i=0;i+k<=n;i++) { ans+=sum[i+k]-sum[i]; } ans/=((n-k+1)); printf("%.10f\n",ans); }
C 題 題目的意思是主人有n個茶杯,每個茶杯有容量。現在給一壺茶,總量為w。希望倒茶滿足條件:每杯茶要超過容量的一半,並且w被倒光,茶杯內的茶水為整數,容量大的杯子內的茶不允許比容量小的杯子內的茶水少。
先給每個茶杯倒一半的水,然後把剩下的水盡量倒到容量大的茶杯裏,倒完為止
#include<string> #include<iostream> #include<cstring> #include<cmath> #include<algorithm> #include<vector> #include<queue> #include<cstdio> using namespace std; int n,m,w; int arr[105]; typedef struct node { int id,val,lim; friend bool operator<(node a,node b){return a.lim<b.lim;} }node; node axx[105]; int main() { int i,j; scanf("%d%d",&n,&w); int lim=0; for(i=0;i<n;i++) { scanf("%d",&arr[i]); lim+=(arr[i]+1)/2; } if(w<lim)printf("-1\n"); else { w-=lim; for(i=0;i<n;i++)axx[i].id=i,axx[i].val=(arr[i]+1)/2,axx[i].lim=arr[i]; sort(axx,axx+n); for(i=n-1;i>=0&&w>0;i--)while(axx[i].lim>axx[i].val&&w>0)axx[i].val++,w--; for(i=0;i<n;i++)arr[axx[i].id]=axx[i].val; for(i=0;i<n;i++) { if(i)printf(" "); printf("%d",arr[i]); } printf("\n"); } }
D 題 給你一個序列ai,首先你可以讓序列中的一個數移動到這個序列的任何一個位置,然後讓你求是否存在一個前綴,使得前綴和等於序列中其余的數的和
解法:掃一遍求前綴和,掃x時有三種情況是yes,第一,1~x的前綴和恰好等於序列總和的一半;第二,存在前綴序列中某一個數跳到了後綴裏,使得新的前綴和滿足條件,
即(1~x+1前綴和-跳出去的數的值)=序列總和的一半;第三,存在後綴序列中某一個數跳到了前綴裏,使得新的前綴和滿足條件,即(1~x-1前綴和+跳進來的數的值)=序列總和的一半,
只要用map來維護前綴和後綴中存在的數即可
#include<string> #include<iostream> #include<cstring> #include<cmath> #include<algorithm> #include<vector> #include<queue> #include<cstdio> #include<map> using namespace std; typedef long long ll; int n,m; ll arr[1000005]; ll sum[1000005]; map<ll,int>dui1,dui2; int main() { int i,j; scanf("%d",&n); for(i=1;i<=n;i++)scanf("%I64d",&arr[i]); dui1.clear(); dui2.clear(); sum[0]=0; for(i=1;i<=n;i++)sum[i]=sum[i-1]+arr[i]; if(sum[n]&1) { printf("NO\n"); } else { for(i=1;i<=n;i++) { if(!dui2.count(arr[i]))dui2[arr[i]]=1; else dui2[arr[i]]++; } for(i=1;i<n;i++) { dui1[arr[i]]=1; dui2[arr[i]]--; if(sum[i]==sum[n]/2) { printf("YES\n"); return 0; } else if(dui1.count(arr[i+1]+sum[i]-sum[n]/2)) { printf("YES\n"); return 0; } else if(dui2[-sum[i]+arr[i]+sum[n]/2]>0) { printf("YES\n"); return 0; } } printf("NO\n"); } return 0; }
E題 題意是一個01背包,壞消息是n<=100000,m<=300000,好消息是w=1,2,3...這個題直接O(nm)去做肯定不行,模擬比賽的時候我心存僥幸大範圍貪心,小範圍dp,然後果斷WA了....
正解是三分法,首先我們把物品以w=1,2,3分類,然後分別排序,並求出前綴和,然後枚舉取用w=3的物品的個數,然後 三分2的個數, 1的個數也就知道了 。而2的個數和是一個單峰函數,
所以可以用三分法
#include<string> #include<iostream> #include<cstring> #include<cmath> #include<algorithm> #include<vector> #include<queue> #include<cstdio> #include<set> using namespace std; typedef long long ll; vector<ll>arr[4]; ll sum[4][300005]; ll n,m; bool cmp(ll a,ll b){return a>b;} ll getans(ll tri,ll dob){return sum[3][tri]+sum[2][dob]+sum[1][m-tri*3-dob*2];} int main() { ll i,j; scanf("%d%d",&n,&m); for(i=0;i<n;i++) { ll w; ll val; scanf("%I64d%I64d",&w,&val); arr[w].push_back(val); } for(i=1;i<=3;i++)sort(arr[i].begin(),arr[i].end(),cmp); for(i=1;i<=3;i++) { sum[i][0]=0; for(j=1;j<=arr[i].size();j++)sum[i][j]=sum[i][j-1]+arr[i][j-1]; for(j=arr[i].size()+1;j<=m;j++)sum[i][j]=sum[i][j-1]; } ll maxn=0; for(i=0;i<=arr[3].size();i++) { if(3*i>m)break; ll l=0,r=(m-3*i)/2; while(r-l>2) { ll rmid=(r*2+l)/3; ll lmid=(l*2+r)/3; ll ans1=getans(i,lmid); ll ans2=getans(i,rmid); if(ans1>ans2)r=rmid; else l=lmid; maxn=max(maxn,ans1); maxn=max(maxn,ans2); } for(j=l;j<=r;j++)maxn=max(getans(i,j),maxn); //printf("%I64d\n",maxn); } printf("%I64d\n",maxn); return 0; }
Educational Codeforces Round 21 A-E題題解