codeforces1073d Berland Fair 思维(暴力删除)
题目大意:一圈人围起来卖糖果,标号从1-n,每个位置的糖果都有自己的价格,一个人拿着钱从q开始走,能买则买,不能买则走到下一家,问最多能买多少件物品。
思路:此题的关键是不能买则走到下一家,一旦走到下一家,我们会发现之前的这家以后无论转几圈我们都买不起,所以直接把这个店删掉就可以了。
于是先将n当成周期,算出此时的sum,和原来的money比较,能买几个周期则买几个周期,然后遍历双向链表,不能买则删去,更新周期和sum,继续判断能不能买得起此时的周期,然后走到下一家店,直到剩下一家店。
由于每家店最多被删去一次,所以时间复杂度是O(n)的,只要注意链表的一些细节处理就可以了。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
//#pragma comment(linker,"/STACK:102400000,102400000") #include<cstdio> #include<algorithm> #include<iostream> #include<vector> #include<map> #include<set> #include<cstring> #include<cmath> #include<queue> #include<stack> #include<stdlib.h> //#include<unordered_map> #define lson l,mid,rt<<1 #define rson mid+1,r,(rt<<1)|1 #define CLR(a,b) memset(a,b,sizeof(a)) #define mkp(a,b) make_pair(a,b) typedef long long ll; using namespace std; inline ll read(){ ll x=0,f=1; char ch=getchar();while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();} return x*f;} const int maxn=2e5+10; struct node{ ll val; int pre,Next; }a[maxn]; ll sum,money,ans; int main(){ int n; cin>>n>>money; for(int i=1;i<=n;i++) { scanf("%lld",&a[i].val); sum+=a[i].val; a[i].pre=i-1,a[i].Next=i+1; } a[1].pre=n,a[n].Next=1; if(money>=sum) { ans+=money/sum*n; money%=sum; } int i=1; while(a[i].Next!=i) { if(money>=a[i].val) { ans++; money-=a[i].val; if(money<=0)break; i=a[i].Next; }else{ a[a[i].pre].Next=a[i].Next; a[a[i].Next].pre=a[i].pre; sum-=a[i].val; n--; if(money>=sum&&a[i].Next!=a[i].pre) { ans+=money/sum*n; money%=sum; } if(money<=0)break; i=a[i].Next; } } if(money>=sum) { ans+=money/sum*n; money%=sum; } printf("%lld\n",ans); }
——愿为泰山而不骄
qq850874665~~