标签:
题目:
Garth likes apples and oranges. Recently he bought N fruits, where each fruit was either an apple or an orange. Then he ate all
N fruits in some order. You are given an int K. Garth observed that at every point in time, if he made a list of the last
K fruits he ate, there were at most K/2 (rounded down) apples in this list. For each valid i, you know that the info[i]-th fruit Garth ate was an apple. (Fruits Garth ate are numbered starting from 1. For example, info[i]=1 means that the very first fruit Garth ate was an apple.) Please find and return the maximum number of apples Garth could have eaten. |
思路:如果所有位置都是未知,那么显然可以把序列每k个分成1段,将第一段放k/2个1,然后复制N/k次可以构造出一个满足条件的序列。另外为了使1最多,我们希望剩下的n%k个数中有尽量多的1,所以第一段的前k/2个数都放1,后面的都放0。现在需要处理某些位置已经是1,而在构造序列中是0的情况。解决的思路是“1换1”,将前k-1个位置中的1变为0,将这一位变为1.需要注意的是和当前位置在同一个k区间的1位置是不允许变为0的。另外如果1边0的位置在上一段中,需要将最后的结果-1
代码:
#include<iostream> #include<stdio.h> #include<string.h> #include<vector> using namespace std; class ApplesAndOrangesHard{ public: int a[100005]; int maximumApples(int n,int k,vector<int> info){ int i,j; memset(a,0,sizeof(a)); for(i=0;i<(k/2);i++){ a[i]=1; } int ans=n/k*(k/2); for(i=0;i<info.size();i++){ int id=info[i]/k+2,pos=info[i]%k; if(!a[pos]){ for(j=0;j<k;j++){ int x=(pos-j-1+k)%k; if(!a[x]) continue; if(x<pos&&a[x]==id) continue; if(x>pos&&a[x]>=id-1) continue; a[x]=0; if(x>pos) ans--; break; } } a[pos]=id; } for(i=0;i<n%k;i++){ if(a[i]) ans++; } return ans; } }; int main(){ int n,k,m; vector<int> a; while(scanf("%d%d%d",&n,&k,&m)!=EOF){ a.clear(); for(int i=1;i<=m;i++){ int x; scanf("%d",&x); a.push_back(x); } ApplesAndOrangesHard t; cout<<t.maximumApples(n,k,a)<<endl; } return 0; }
标签:
原文地址:http://blog.csdn.net/u011822304/article/details/45869377