zoukankan      html  css  js  c++  java
  • Codeforces Round#413 Div.2

    A. Carrot Cakes

    题面

    In some game by Playrix it takes t minutes for an oven to bake k carrot cakes, all cakes are ready at the same moment t minutes after they started baking. Arkady needs at least n cakes to complete a task, but he currently don't have any. However, he has infinitely many ingredients and one oven. Moreover, Arkady can build one more similar oven to make the process faster, it would take d minutes to build the oven. While the new oven is being built, only old one can bake cakes, after the new oven is built, both ovens bake simultaneously. Arkady can't build more than one oven.

    Determine if it is reasonable to build the second oven, i.e. will it decrease the minimum time needed to get n cakes or not. If the time needed with the second oven is the same as with one oven, then it is unreasonable.

    题意

    问有没有必要另起炉灶

    如果时间能节省当然有必要啦~

    代码

    #include <bits/stdc++.h>
    using namespace std;
    
    int n;
    int t;
    int k;
    int d;
    
    int main()
    {
    	cin>>n>>t>>k>>d;
    	if (k>=n) return 0*puts("NO");
    	int guo=(n%k==0)?n/k:n/k+1;
    	if ((guo-1)*t>d) return 0*puts("YES");
    	return 0*puts("NO");
    } 
    

    B. T-shirt buying

    题面

    A new pack of n t-shirts came to a shop. Each of the t-shirts is characterized by three integers pi, ai and bi, where pi is the price of the i-th t-shirt, ai is front color of the i-th t-shirt and bi is back color of the i-th t-shirt. All values pi are distinct, and values ai and bi are integers from 1 to 3.

    m buyers will come to the shop. Each of them wants to buy exactly one t-shirt. For the j-th buyer we know his favorite color cj.

    A buyer agrees to buy a t-shirt, if at least one side (front or back) is painted in his favorite color. Among all t-shirts that have colors acceptable to this buyer he will choose the cheapest one. If there are no such t-shirts, the buyer won't buy anything. Assume that the buyers come one by one, and each buyer is served only after the previous one is served.

    You are to compute the prices each buyer will pay for t-shirts.

    题意

    按照排队顺序,每个人都想买到有喜欢颜色的衣服,每个人都想省钱。

    掏出一个优先队列。

    代码

    #include <bits/stdc++.h>
    using namespace std;
    
    int n;
    int m;
    int x;
    class Tshirt{
    	public:
    		int p,a,b,no;
    		bool choose;
    		friend bool operator< (Tshirt q,Tshirt w)
    		{
    			return q.p>w.p;
    		}
    }a[200010]; 
    priority_queue<Tshirt> q1;
    priority_queue<Tshirt> q2;
    priority_queue<Tshirt> q3;
    
    int main()
    {
    	cin>>n;
    	for (int i=1;i<=n;i++) cin>>a[i].p;
    	for (int i=1;i<=n;i++) cin>>a[i].a;
    	for (int i=1;i<=n;i++) cin>>a[i].b;
    	for (int i=1;i<=n;i++) a[i].no=i,a[i].choose=0;
    	
    	for (int i=1;i<=n;i++)
    	{
    		if (a[i].a==1) q1.push(a[i]);
    		if (a[i].a==2) q2.push(a[i]);
    		if (a[i].a==3) q3.push(a[i]);
    		
    		if (a[i].b==1) q1.push(a[i]);
    		if (a[i].b==2) q2.push(a[i]);
    		if (a[i].b==3) q3.push(a[i]);
    	}
    	
    	cin>>m;
    	while (m--)
    	{
    		cin>>x;
    		if (x==1)
    		{
    			if (q1.empty()) 
    			{
    				cout<<"-1 ";
    				continue;
    			}
    			while (!q1.empty() && a[q1.top().no].choose) q1.pop();
    			if (q1.empty()) 
    			{
    				cout<<"-1 ";
    				continue;
    			}
    			Tshirt now=q1.top();q1.pop();
    			cout<<now.p<<" ";
    			a[now.no].choose=1;
    		}
    		else if (x==2)
    		{
    			if (q2.empty()) 
    			{
    				cout<<"-1 ";
    				continue;
    			}
    			while (!q2.empty() && a[q2.top().no].choose) q2.pop();
    			if (q2.empty()) 
    			{
    				cout<<"-1 ";
    				continue;
    			}
    			Tshirt now=q2.top();q2.pop();
    			cout<<now.p<<" ";
    			a[now.no].choose=1;
    		}
    		else if (x==3)
    		{
    			if (q3.empty()) 
    			{
    				cout<<"-1 ";
    				continue;
    			}
    			while (!q3.empty() && a[q3.top().no].choose) q3.pop();
    			if (q3.empty()) 
    			{
    				cout<<"-1 ";
    				continue;
    			}
    			Tshirt now=q3.top();q3.pop();
    			cout<<now.p<<" ";
    			a[now.no].choose=1;
    		}
    	}
    } 
    

    C. Fountains

    题面

    Arkady plays Gardenscapes a lot. Arkady wants to build two new fountains. There are n available fountains, for each fountain its beauty and cost are known. There are two types of money in the game: coins and diamonds, so each fountain cost can be either in coins or diamonds. No money changes between the types are allowed.

    Help Arkady to find two fountains with maximum total beauty so that he can buy both at the same time.

    题意

    Arkady有钻石和硬币,问他买最美的两块地要花多少钱

    我们考虑花钻石和硬币的情况,显然最美的就好了。

    我们考虑只花钻石的情况,用一个线段树维护区间最大值,ans=p+tree[1,rest]。

    代码

    #include <bits/stdc++.h>
    using namespace std;
    
    int n,c,d;
    int tree[2][100010*4];
    int ans;
    int xx,yy;
    char zz;
    int maxc,maxd;
    
    void pushup(int k,int typ)
    {
    	tree[typ][k]=max(tree[typ][k<<1],tree[typ][k<<1|1]);
    	return;
    } 
    
    void update(int pos,int val,int l,int r,int o,int typ)  //把tree[typ][pos]更新 
    {  
        if(l==r)
        {  
            tree[typ][o]=max(tree[typ][o],val);
            return;
        }  
        int mid{(l+r)>>1};  
        if(pos<=mid)  
            update(pos,val,l,mid,o<<1,typ);  
        else  
            update(pos,val,mid+1,r,o<<1|1,typ);  
        pushup(o,typ);  
    }  
    
    int query(int L,int R,int l,int r,int o,int typ)  
    {  
        int ret=0;  
        if (L>R) return 0; 
        if(L<=l&&r<=R) return tree[typ][o];  
        int mid{(l+r)>>1};  
        if(L<=mid)  
            ret=max(ret,query(L,R,l,mid,o<<1,typ));  
        if(R>mid)  
            ret=max(ret,query(L,R,mid+1,r,o<<1|1,typ));  
        return ret;  
    }
    
    int main() 
    {
    	cin>>n>>c>>d;
    	memset(tree,0,sizeof(tree));
    	for (int i=1;i<=n;i++) 
    	{
    		cin>>xx>>yy>>zz;
    		if (zz=='C')
    		{
    			if (yy>c) continue; //价格超过上线 
    			maxc=max(maxc,xx); //选一个的时候 
    			int check=query(1,c-yy,1,c,1,0); //从1到c-yy中选择p最大的。 
    			if (check) ans=max(ans,xx+check); //如果存在的话就取,不存在不取 
    			update(yy,xx,1,c,1,0);  //把该点加进去更新 
    		}
    		if (zz=='D')
    		{
    			if (yy>d) continue;
    			maxd=max(maxd,xx);
    			int check=query(1,d-yy,1,d,1,1);
    			if (check) ans=max(ans,xx+check);
    			update(yy,xx,1,d,1,1);  
    		}
    	}
    	if (maxc && maxd) ans=max(ans,maxc+maxd);
    	cout<<ans;
    }
    

    D. Field expansion

    题面

    In one of the games Arkady is fond of the game process happens on a rectangular field. In the game process Arkady can buy extensions for his field, each extension enlarges one of the field sizes in a particular number of times. Formally, there are n extensions, the i-th of them multiplies the width or the length (by Arkady's choice) by ai. Each extension can't be used more than once, the extensions can be used in any order.

    Now Arkady's field has size h × w. He wants to enlarge it so that it is possible to place a rectangle of size a × b on it (along the width or along the length, with sides parallel to the field sides). Find the minimum number of extensions needed to reach Arkady's goal.

    题意

    将a,b变成w,h。给出一堆ai拿来乘。

    因为ai>=2,所以有(1<<17)>100000。所以取最大的34个就行了,如果最大的只有2,可以直接处理。我用的是dfs剪枝,实际上如果用2以上的会大大降低。

    代码

    #include <bits/stdc++.h>
    using namespace std;
    
    using ll=long long;
    ll a,b,h,w,n; 
    priority_queue<ll> q; 
    ll e[100010];
    using qwq = pair< pair<int,int> , int >  ;
    map<qwq,int> m;
    
    ll dfs(ll now,ll weigh,ll height)
    {
    	if (m.count(make_pair( make_pair(weigh,height) ,now)) ) return 100;
    	if (m.count(make_pair( make_pair(height,weigh) ,now)) ) return 100;
    	m[make_pair( make_pair(weigh,height) ,now)]=1;
    	m[make_pair( make_pair(height,weigh) ,now)]=1;
    	if (weigh>=a && height>=b) return now-1;
    	if (weigh>=b && height>=a) return now-1;
    	if (now>n) return 100;
    	
    	ll test1=dfs(now+1,weigh*e[now],height);
    	//if (test1!=-1) return test1;
    	ll test2=dfs(now+1,weigh,height*e[now]);
    	//if (test2!=-1) return test2;
    	
    	return min(test1,test2);
    }
    
    int main()
    {
    	cin>>a>>b>>h>>w>>n;	
    	for (int i=1;i<=n;i++) 
    	{
    		cin>>e[i];
    		q.push(e[i]);
    	}
    	n=min(n,34LL);
    	for (int i=1;i<=n;i++) 
    	{
    		e[i]=q.top();
    		q.pop();
    	}
    	ll ans=dfs(1,h,w);
    	if (ans!=100) cout<<ans;else cout<<-1;
    } 
    

    E. Aquarium decoration

    题面

    Arkady and Masha want to choose decorations for thier aquarium in Fishdom game. They have n decorations to choose from, each of them has some cost. To complete a task Arkady and Masha need to choose exactly m decorations from given, and they want to spend as little money as possible.

    There is one difficulty: Masha likes some a of the given decorations, Arkady likes some b of the given decorations. Some decorations may be liked by both Arkady and Masha, or not be liked by both. The friends want to choose such decorations so that each of them likes at least k decorations among the chosen. Help Masha and Arkady find the minimum sum of money they need to spend.

    题意

    带双重约束的最小费用问题。

    嗯。反正我是不会做QwQ。

    红名玩家题解

    来自本场第三名 红名玩家subscriber。

    他的做法大概是先分类:两种都被喜欢的,只有a喜欢的,只有b喜欢的,都不喜欢的

    然后枚举都喜欢的个数,用二分来做,二分枚举装饰单价,如果这个单价合适,则会更新cost,然后尝试更新ans。从而得到解

    解法巧妙之处在于二分这个单价。

    而搜了搜题解,网上还有一种做法也是类似于分类后处理的,我觉得在细节处理上不如这种巧妙和简洁。

    代码如下,已做修改。

    代码

    #include<bits/stdc++.h>
    using namespace std;
    
    using ll = long long;
    int n,m,k;
    int t,x;
    int c[200010];
    int f1[200010];
    int f2[200010];
    
    vector<int> w, a, b;
    vector<int> d;
    vector<ll> ww, aa, bb, dd;
    
    int main()
    {	
    	ios::sync_with_stdio(false);
    	cin>>n>>m>>k;
    	for (int i=0;i<n;i++) cin>>c[i];
    	cin>>t;
    	for (int i=0;i<t;i++)
    	{
    		cin>>x;
    		f1[x-1]=1;
    	}
    	cin>>t;
    	for (int i=0;i<t;i++)
    	{
    		cin>>x;
    		f2[x-1]=1;
    	}
    	
    	for (int i = 0; i < n; i++) 
    	{
    		if (f1[i] && f2[i]) w.push_back(c[i]);
    		else if (f1[i]) a.push_back(c[i]); 
    		else if (f2[i]) b.push_back(c[i]);
    		else d.push_back(c[i]);
    	}
    	sort(w.begin(), w.end());
    	sort(a.begin(), a.end());
    	sort(b.begin(), b.end());
    	sort(d.begin(), d.end());
    
    	
    	ww.push_back(0);
    	aa.push_back(0);
    	bb.push_back(0);
    	dd.push_back(0);
    	for (int i = 0; i < w.size(); i++) ww.push_back(ww.back() + w[i]);
    	for (int i = 0; i < a.size(); i++) aa.push_back(aa.back() + a[i]);
    	for (int i = 0; i < b.size(); i++) bb.push_back(bb.back() + b[i]);
    	for (int i = 0; i < d.size(); i++) dd.push_back(dd.back() + d[i]);
    
    	ll ans = 1e18 + 1;
    
    	for (int i = 0; i <= w.size(); i++) 
    	{
    		ll cost = ww[i];
    		int need = max(0, k - i);
    		if (need > a.size() || need > b.size() || i + need * 2 > m) continue;
    		cost += aa[need];
    		cost += bb[need];
    
    		int re = m - i - 2 * need;
    
    		if (a.size() - need + b.size() - need + d.size() < re) continue;
    
    		if (re > 0) 
    		{
    			int l = 0;
    			int r = 1e9 + 1;
    			while (l < r) 
    			{
    				int mid = (l + r) / 2;
    				int cnt = 0;
    				int h = upper_bound(a.begin(), a.end(), mid) - a.begin();
    				cnt += max(0, h - need);
    				h = upper_bound(b.begin(), b.end(), mid) - b.begin();
    				cnt += max(0, h - need);
    				h = upper_bound(d.begin(), d.end(), mid) - d.begin();
    				cnt += max(0, h);
    				if (cnt >= re) r = mid; else l = mid + 1;
    			}
    			{	
    				int mid = l;
    				int cnt = 0;
    		
    				int h = upper_bound(a.begin(), a.end(), mid) - a.begin();
    				cnt += max(0, h - need);
    				if (h > need) cost += aa[h] - aa[need];
    		
    				h = upper_bound(b.begin(), b.end(), mid) - b.begin();
    				cnt += max(0, h - need);
    				if (h > need) cost += bb[h] - bb[need];
    		
    				h = upper_bound(d.begin(), d.end(), mid) - d.begin();
    				cnt += max(0, h);
    				cost += dd[h];
    		
    				if (cnt > re) cost -= mid * (cnt - re);
    			}
    		}
    		ans = min(ans, cost);
    	}
    	if (ans > 1e17) ans = -1;
    	cout << ans << endl;
    	return 0;
    }
    

    F. Beautiful fountains rows

    题面

    Butler Ostin wants to show Arkady that rows of odd number of fountains are beautiful, while rows of even number of fountains are not.

    The butler wants to show Arkady n gardens. Each garden is a row of m cells, the i-th garden has one fountain in each of the cells between li and ri inclusive, and there are no more fountains in that garden. The issue is that some of the gardens contain even number of fountains, it is wrong to show them to Arkady.

    Ostin wants to choose two integers a ≤ b and show only part of each of the gardens that starts at cell a and ends at cell b. Of course, only such segments suit Ostin that each garden has either zero or odd number of fountains on this segment. Also, it is necessary that at least one garden has at least one fountain on the segment from a to b.

    Help Ostin to find the total length of all such segments, i.e. sum up the value (b - a + 1) for each suitable pair (a, b).

    题意

    用一些区间去覆盖,合法区间为,对所有花园覆盖的喷泉数量为奇数,但是至少覆盖到了温泉。

    问所有区间长度为多少。

    代码

    //
    

    G. Cut the pie

    题面

    Arkady reached the n-th level in Township game, so Masha decided to bake a pie for him! Of course, the pie has a shape of convex n-gon, i.e. a polygon with n vertices.

    Arkady decided to cut the pie in two equal in area parts by cutting it by a straight line, so that he can eat one of them and give the other to Masha. There is a difficulty because Arkady has already put a knife at some point of the pie, so he now has to cut the pie by a straight line passing trough this point.

    Help Arkady: find a line that passes through the point Arkady has put a knife into and cuts the pie into two parts of equal area, or determine that it's impossible. Your program has to quickly answer many queries with the same pie, but different points in which Arkady puts a knife.

    题意

    给了你一个派。你知道这个派是n边形的,给你他所有点的坐标和刀的起点,问切一半的角度是多少。

    代码

    //瓦没收了蛋糕并一口吃掉了。
    

    赛后总结

    混合场,做完以后大涨rating。

    可惜C并没有在比赛中做出,看出来太晚了。

    其实codeforces上分的话还是需要点手速的。

    叶姐姐在这场还抽到了衣服qwq?

    比赛链接

    http://codeforces.com/contest/799

  • 相关阅读:
    如何实现一个串行promise
    单机,分布式和集群的区别
    ERP & CRM
    CDN working principle diagram
    公众平台服务号、订阅号、企业号的相关说明
    DMZ的原理与应用
    ICP备案接入商
    DMZ主机
    浅析localstorage、sessionstorage
    Repeater+AspNetPager+Ajax留言板
  • 原文地址:https://www.cnblogs.com/EDGsheryl/p/6865151.html
Copyright © 2011-2022 走看看