A. Curriculum Vitae
题目链接:http://codeforces.com/contest/846/problem/A
题目意思:给你一个只包含0-1的数组,现在要求去可以去掉一些元素使得不会出现10子串,并且剩下的元素还要最大,输出剩下元素的数量。
题目思路:由于0不可能出现1的后面所以,最后出现必定是000011111,这样的串,所以我们暴力枚举每一位k,设a={1,2,3……,k-1}中0的数量,b=(k+1,k+2,…………n}中1的数量,这样tmp=a+b+1,那么ans=max(tmp);
代码:
1 /* *********************************************** 2 Author :xiaowuga 3 Created Time :2017年10月04日 星期三 09时19分12秒 4 File Name :A.cpp 5 ************************************************ */ 6 #include <bits/stdc++.h> 7 #define mem(s,ch) memset(s,ch,sizeof(s)) 8 typedef long long LL; 9 #define inf 0x3f3f3f3f 10 const long long N=1000000; 11 const long long mod=1e9+7; 12 using namespace std; 13 int main(){ 14 ios::sync_with_stdio(false);cin.tie(0); 15 int n; 16 int a[1001]; 17 cin>>n; 18 for(int i=0;i<n;i++) cin>>a[i]; 19 int ans=0; 20 for(int i=0;i<n;i++){ 21 int t=0; 22 for(int j=0;j<n;j++){ 23 if(j<i&&!a[j]) t++; 24 if(j>i&&a[j]) t++; 25 } 26 ans=max(ans,t+1); 27 } 28 cout<<ans<<endl; 29 return 0; 30 }
B. Math Show
题目链接:http://codeforces.com/contest/846/problem/B
题目意思:现在有n个任务每个任务有k个子任务,完成一个任务可以得到一份,每完成一个任务的所有子任务,可以额外获得一分,所有任务的子任务同一下标的子任务都有一样的花费时间,但是不同子任务的花费时间可能是不一样的,现在有M的时间,求在M时间内可以获得最大的得分是多少?
题目思路:我们发现n比较小,最大只有45,所以我们可以暴力枚举完成了多少个大任务,剩下的时间,根据尽量先完成花费时间少的子任务,然后维护最大的得分。
代码:
1 /* *********************************************** 2 Author :xiaowuga 3 Created Time :2017年10月04日 星期三 09时54分31秒 4 File Name :B.cpp 5 ************************************************ */ 6 #include <bits/stdc++.h> 7 #define mem(s,ch) memset(s,ch,sizeof(s)) 8 typedef long long LL; 9 #define inf 0x3f3f3f3f 10 const long long N=1000000; 11 const long long mod=1e9+7; 12 using namespace std; 13 int main(){ 14 ios::sync_with_stdio(false);cin.tie(0); 15 int n,k; 16 LL M; 17 LL a[50]; 18 LL sum=0; 19 cin>>n>>k>>M; 20 for(int i=0;i<k;i++) { 21 cin>>a[i]; 22 sum+=a[i]; 23 } 24 sort(a,a+k); 25 int ans=0; 26 for(int i=0;i<=n;i++){ 27 LL t=sum*i; 28 int tmp=i*k+i; 29 if(t>M) break; 30 t=M-t; 31 for(int j=0;j<k;j++){ 32 for(int p=1;p<=n-i;p++){ 33 if(t>=a[j]){ 34 t-=a[j]; 35 tmp++; 36 } 37 else{ 38 j=k;break; 39 } 40 } 41 } 42 ans=max(ans,tmp); 43 } 44 cout<<ans<<endl; 45 return 0; 46 }
C. Four Segments
题目链接:http://codeforces.com/contest/846/problem/C
题目意思:现在有一个数列p包含n个元素,然后现在要找到三个分割点a,b,c(表示下标)使得ans=sum(0,a)-sum(a,b)+sum(b,c)-sum(c,n),数组下标从1开始,sum(x,y)表示(p[x+1],p[x+2],p[x+3],p[x+4]…………+p[y])的和,现在要是ans最大,请输出这a,b,c这三个下标,abc可以相等表示区间为空。
题目思路:前缀和处理这个是肯定的,然后朴素的想法就是暴力n^3去枚举abc的位置,然后求最大值,但是明显对于题目数据这个复杂度太大了。我们需要把有他优化成n^2,一个简单的想法我们可以枚举a和c,然后对a,c这个区间我们寻去一个pos,使得sum(a,pos)最小,则sum(pos,b)就会最大,因为sum(a,c)对于确定的ac是不会变的,我们知道sum(a,pos)=presum[pos]-presum[a],枚举时候presum[a]已经确定了,所以我们我们只需要是presum[pos]尽量小,就可以了。这样暴力的扫一遍维护一个最大值就可以得到答案了。
代码:
1 /* *********************************************** 2 Author :xiaowuga 3 Created Time :2017年10月04日 星期三 11时02分34秒 4 File Name :C.cpp 5 ************************************************ */ 6 #include <bits/stdc++.h> 7 #define mem(s,ch) memset(s,ch,sizeof(s)) 8 typedef long long LL; 9 #define inf 0x3f3f3f3f 10 const long long N=1000000; 11 const long long mod=1e9+7; 12 using namespace std; 13 LL dp[5050]={0}; 14 LL sum(int l,int r){ 15 return dp[r]-dp[l]; 16 } 17 int main(){ 18 ios::sync_with_stdio(false);cin.tie(0); 19 int n; 20 cin>>n; 21 for(int i=1;i<=n;i++){ 22 LL t; 23 cin>>t; 24 dp[i]=dp[i-1]+t; 25 } 26 LL ans=-1e15,a,b,c; 27 for(int i=0;i<=n;i++){ 28 LL k=dp[i],pos=i; 29 for(int j=i;j<=n;j++){ 30 if(dp[j]<k){ 31 k=dp[j]; pos=j; 32 } 33 LL cur=sum(0,i)-sum(i,pos)+sum(pos,j)-sum(j,n); 34 if(ans<cur){ 35 ans=cur; 36 a=i,b=pos,c=j; 37 } 38 } 39 } 40 cout<<a<<' '<<b<<' '<<c<<endl; 41 return 0; 42 }
D. Monitor
题目链接:http://codeforces.com/contest/846/problem/D
题目意思:现在有一个显示器,有n×m个像素点,最后会有q点是坏掉的,每个点给出三个参数x,y,t,表示坐标为(x,y)的点在t时刻以后(包括t时刻)都是坏掉的,询问是否存在一个k×k的矩形区域内都是坏掉的点,如果不存在输出-1,如果存在输出第一个出现这样坏掉的矩形出现时刻。
题目思路:二维前缀和+二分(可能有人用的是什么二维树状数组,但是不会啊,只会暴力啊,不会高端数据结构),直接看代码吧!很暴力的思想,每次二分处理一下二维前缀和,然后n^2验证。
代码:
1 /* *********************************************** 2 Author :xiaowuga 3 Created Time :2017年10月04日 星期三 13时50分59秒 4 File Name :D.cpp 5 ************************************************ */ 6 #include <bits/stdc++.h> 7 typedef long long LL; 8 #define endl "\n" 9 #define inf 0x3f3f3f3f 10 const long long N=1000000; 11 const long long mod=1e9+7; 12 using namespace std; 13 int M[501][501]={0}; 14 int mt; 15 int n,m,k,q; 16 struct node{ 17 int x,y,t; 18 bool operator <(const node &x) const{ 19 return t<x.t; 20 } 21 }; 22 vector<node>a; 23 int solve(int i,int j){ 24 return M[i][j]-M[i-k][j]-M[i][j-k]+M[i-k][j-k]; 25 } 26 void AC(){ 27 int l=0,r=1e9+7; 28 while(l<r){ 29 int md=l+(r-l)/2; 30 for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) M[i][j]=0; 31 for(int i=0;i<q;i++) if(a[i].t<=md) M[a[i].x][a[i].y]=1; 32 33 for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) M[i][j]+=M[i-1][j]+M[i][j-1]-M[i-1][j-1]; 34 int flag=0; 35 for(int i=k;i<=n;i++){ 36 for(int j=k;j<=m;j++){ 37 int num=solve(i,j); 38 if(num==k*k){ 39 flag=1; 40 i=n+1; 41 break; 42 } 43 } 44 } 45 if(flag) r=md; 46 else l=md+1; 47 } 48 cout<<l<<endl; 49 } 50 int main(){ 51 ios::sync_with_stdio(false);cin.tie(0); 52 mt=-1; 53 cin>>n>>m>>k>>q; 54 a.resize(q); 55 for(int i=0;i<q;i++){ 56 cin>>a[i].x>>a[i].y>>a[i].t; 57 M[a[i].x][a[i].y]=1; 58 mt=max(mt,a[i].t); 59 } 60 sort(a.begin(),a.end()); 61 for(int i=1;i<=n;i++){ 62 for(int j=1;j<=m;j++){ 63 M[i][j]+=M[i-1][j]+M[i][j-1]-M[i-1][j-1]; 64 } 65 } 66 int flag=0; 67 for(int i=k;i<=n;i++){ 68 for(int j=k;j<=m;j++){ 69 int num=solve(i,j); 70 if(num==k*k){ 71 flag=1; 72 i=n+1; 73 break; 74 } 75 } 76 } 77 if(flag) AC(); 78 else cout<<-1<<endl; 79 return 0; 80 }