2022.07.12 暑假集训 个人排位赛(七)

2022.07.12 暑假集训 个人排位赛(七)

赛后反省

不至于,真不至于,被两道题卡死之后完全不去想其他题目了。背包那题确实简单,补题过了。当时J题看漏了还能有黑色Queen,H题一直认为自己的想法是正确的,而且根据提交结果反馈一直认为是精度问题。不够努力吧只能说,而且有一题优先队列水题用线段树去码,中间还写错了一点,笑麻了。

Problem C

出处

Codeforces-851B

题解

判断三个点不共线并且长度相等即可。


// Good Good Study, Day Day AC.
#include <iostream>
#include <stdio.h>
#include <cstdio>
#include <stdlib.h>
#include <string>
#include <string.h>
#include <cstring>
#include <math.h>
#include <cmath>
#include <queue>
#include <deque>
#include <stack>
#include <vector>
#include <map>
#include <algorithm>
#include <unordered_map>
#include <unordered_set>
#define ffor(i,a,b) for(int i=(a) ;i<=(b) ;i++)
#define rrep(i,a,b) for(int i=(a) ;i>=(b) ;i--)
#define mst(v,s) memset(v,s,sizeof(v))
#define IOS ios::sync_with_stdio(false),cin.tie(0)
#define ll long long
#define INF 0x7f7f7f7f7f7f7f7f
#define inf 0x7f7f7f7f
#define PII pair<int,int>
#define int long long

using namespace std;

int n, T = 1, m;


void ready()
{

}

int dis(int ax,int ay,int bx,int by){
    return (by-ay)*(by-ay)+(bx-ax)*(bx-ax);
}

void work()
{
    int ax,ay,bx,by,cx,cy;
    cin>>ax>>ay>>bx>>by>>cx>>cy;
    if(dis(ax,ay,bx,by)!=dis(bx,by,cx,cy) || (by-ay)*(cx-bx)==(cy-by)*(bx-ax)){
        cout<<"No";
    }
    else{
        cout<<"Yes";
    }
}

signed main()
{
	IOS;
    ready();
	//cin>>T;
	while (T--) {
		work();
	}
	return 0;
}





Problem D

出处

Codeforces-854C

题解

首先处理损失最大的。每个飞机不能提前飞,那么就是在该时间之后找第一个能够起飞的点。

将能起飞的点作为数组,每个点存k+1,k+2,…,k+n,然后建线段树,每次从一个时间点起飞之后,把这个点变成INF,最后问题就变成了单点修改,区间求最小值的问题。

代码


// Good Good Study, Day Day AC.
#include <iostream>
#include <stdio.h>
#include <cstdio>
#include <stdlib.h>
#include <string>
#include <string.h>
#include <cstring>
#include <math.h>
#include <cmath>
#include <queue>
#include <deque>
#include <stack>
#include <vector>
#include <map>
#include <algorithm>
#include <unordered_map>
#include <unordered_set>
#define ffor(i,a,b) for(int i=(a) ;i<=(b) ;i++)
#define rrep(i,a,b) for(int i=(a) ;i>=(b) ;i--)
#define mst(v,s) memset(v,s,sizeof(v))
#define IOS ios::sync_with_stdio(false),cin.tie(0)
#define ll long long
#define INF 0x7f7f7f7f7f7f7f7f
#define inf 0x7f7f7f7f
#define PII pair<int,int>
#define int long long

using namespace std;

const int N=3e5+5;
int n, T = 1, m;
int k;

struct Air{
    int val,tim,st;
}a[N];
bool f[N];
int cn[N];
int t[N];
vector<int> loc;

struct Tree{
    int l,r,minn;
}tr[N*4];

void pushup(Tree& u,Tree& l,Tree& r){
    u.minn=min(l.minn,r.minn);
}

void build(int u,int l,int r){
    if(l==r) tr[u]={l,r,t[l]};
    else{
        tr[u]={l,r};
        int mid=tr[u].l+tr[u].r>>1;
        build(u<<1,l,mid); build(u<<1|1,mid+1,r);
        pushup(tr[u],tr[u<<1],tr[u<<1|1]);
    }
}

void modify(int u,int x){
    if(x==tr[u].l && tr[u].l==tr[u].r) tr[u].minn=INF;
    else{
        int mid=tr[u].l+tr[u].r>>1;
        if(x<=mid) modify(u<<1,x);
        if(mid<x) modify(u<<1|1,x);
        pushup(tr[u],tr[u<<1],tr[u<<1|1]);
    }
}

int query(int u,int l,int r){
    if(l<=tr[u].l && tr[u].r<=r) return tr[u].minn;
    int mid=tr[u].l+tr[u].r>>1;
    int lmin=INF,rmin=INF;
    if(l<=mid) lmin=query(u<<1,l,r);
    if(mid<r) rmin=query(u<<1|1,l,r);
    return min(lmin,rmin);
}


bool cmp(Air i,Air j){
    if(i.val==j.val){
        return i.tim<j.tim;
    }
    return i.val>j.val;
}

void ready()
{
    cin>>n>>k;
    ffor(i,1,n){
        int c;
        cin>>c;
        a[i]={c,i};
        t[i]=i+k;
        loc.push_back(i+k);
    }
    sort(a+1,a+n+1,cmp);
    ffor(i,1,n){
        a[i].st=lower_bound(loc.begin(),loc.end(),a[i].tim)-loc.begin()+1;
        //cout<<a[i].tim<<' '<<a[i].st<<'\n';
    }
    build(1,1,n);
    int ans=0;
    //cout<<query(1,3,5);
    ffor(i,1,n){
        int id=query(1,a[i].st,n);
        modify(1,id-k);
        ans+=(id-a[i].tim)*a[i].val;
        cn[a[i].tim]=id;
       // cout<<a[i].val<<' '<<a[i].tim<<' '<<a[i].st<<' '<<id<<'\n';
       // cout<<query(1,1,n)<<'\n';
    }
    cout<<ans<<'\n';
    ffor(i,1,n) cout<<cn[i]<<' ';
}


void work()
{


}

signed main()
{
	IOS;
    ready();
	//cin>>T;
	while (T--) {
		work();
	}
	return 0;
}





Problem E

出处

Codeforces-864E

题解

背包问题的变形。

首先,先按紧急程度排序,按照d从小到大排。如果相等,让t大的排前面。背包容量为最大的d。

d p [ i ] dp[i] dp[i]表示在第i个时间点能够获得的最大价值。

每次从后往前看,如果一个 d p [ i ] dp[i] dp[i]能够获得价值,并且 i + t < d i+t<d i+t<d,说明当前的物品可以放入背包。数据量比较小,每次保存后更新第i+t个时间获得最大价值的物品顺序即可。

代码



// Good Good Study, Day Day AC.
#include <iostream>
#include <stdio.h>
#include <cstdio>
#include <stdlib.h>
#include <string>
#include <string.h>
#include <cstring>
#include <math.h>
#include <cmath>
#include <queue>
#include <deque>
#include <stack>
#include <vector>
#include <map>
#include <algorithm> 
#include <unordered_map>
#include <unordered_set>
#define ffor(i,a,b) for(int i=(a) ;i<=(b) ;i++)
#define rrep(i,a,b) for(int i=(a) ;i>=(b) ;i--)
#define mst(v,s) memset(v,s,sizeof(v))
#define IOS ios::sync_with_stdio(false),cin.tie(0)
#define ll long long
#define INF 0x7f7f7f7f7f7f7f7f
#define inf 0x7f7f7f7f
#define PII pair<int,int>
#define int long long

using namespace std;

const int N = 105;

int n, T = 1, maxn;
struct Baby {
	int t, d, p, id;
}a[N];
vector<int> ans[3005];
bool f[3005];
int dp[3005];

bool cmp(Baby i, Baby j) {
	if (i.d == j.d) return i.t > j.t;
	return i.d < j.d;
}

void ready()
{
	cin >> n;
	ffor(i, 1, n)
	{
		cin >> a[i].t >> a[i].d >> a[i].p;
		maxn = max(maxn, a[i].d);
		a[i].id = i;
	}
	sort(a + 1, a + n + 1, cmp);
	f[0] = true;
	ffor(i, 1, n) {
		int t = a[i].t, d = a[i].d, p = a[i].p, id = a[i].id;
		rrep(j, maxn, 0) {
			if (f[j] && j + t < d) {
				f[j + t] = true;
				if (dp[j + t] <= dp[j] + p) {
					dp[j + t] = dp[j] + p;
					if(ans[j + t].size())
						ans[j + t].clear();
					ans[j + t].insert(ans[j + t].begin(), ans[j].begin(), ans[j].end());
					ans[j + t].push_back(id);
				}
			}
		}
	}
	int all = 0, ansi = 0;
	ffor(i, 1, maxn) {
		if (dp[i] > all) {
			all = dp[i];
			ansi = i;
		}
	}
	cout << all << '\n';
	cout << ans[ansi].size() << '\n';
	for (auto item : ans[ansi]) {
		cout << item << ' ';
	}
}


void work()
{

}

signed main()
{
	IOS;
	//	cin>>T;
	while (T--) {
		ready();
		work();
	}
	return 0;
}





Problem F

出处

Codeforces-1263C

题解

分块。

代码


// Good Good Study, Day Day AC.
#include <iostream>
#include <stdio.h>
#include <cstdio>
#include <stdlib.h>
#include <string>
#include <string.h>
#include <cstring>
#include <math.h>
#include <cmath>
#include <queue>
#include <deque>
#include <stack>
#include <vector>
#include <map>
#include <algorithm>
#include <unordered_map>
#include <unordered_set>
#define ffor(i,a,b) for(int i=(a) ;i<=(b) ;i++)
#define rrep(i,a,b) for(int i=(a) ;i>=(b) ;i--)
#define mst(v,s) memset(v,s,sizeof(v))
#define IOS ios::sync_with_stdio(false),cin.tie(0)
#define ll long long
#define INF 0x7f7f7f7f7f7f7f7f
#define inf 0x7f7f7f7f
#define PII pair<int,int>
#define int long long

using namespace std;

int n, T = 1, m;


void ready()
{

}

stack<int> ans;

void work()
{
    cin>>n;
    int k=1;
    while(k<=n){
        ans.push(n/k);
        k=n/(n/k)+1;
    }
    ans.push(0);
    cout<<ans.size()<<'\n';
    while(ans.size()){
        cout<<ans.top()<<' ';
        ans.pop();
    }
    cout<<'\n';

}

signed main()
{
	IOS;
    ready();
	cin>>T;
	while (T--) {
		work();
	}
	return 0;
}





Problem H

出处

Codeforces-939E

题解(cyp)

解题详细思路
  1. 为了使max-mean最大,可以贪心考虑,一方面尽量使max更大,另一方面尽量使mean更小
  2. 为了使max尽可能大,考虑将S中的最大值加入子集
  3. 为了使mean尽可能小,考虑将尽可能多的小的值加入子集,降低平均值
算法重点与难点

对上述贪心在数学方面的证明
1.可以注意到,假设max更新后增加了x,mean会增加x/cnt,其中cnt为子集中元素的个数,显然max-mean不会减小
2.小的值加入到子集后随着S的增加,最优解不会使得这些值移出子集,因为总体平均值在增加,需要越来越多小的值来减少平均值。

代码


// Good Good Study, Day Day AC.
#include <iostream>
#include <stdio.h>
#include <cstdio>
#include <stdlib.h>
#include <string>
#include <string.h>
#include <cstring>
#include <math.h>
#include <cmath>
#include <queue>
#include <deque>
#include <stack>
#include <vector>
#include <map>
#include <algorithm>
#include <unordered_map>
#include <unordered_set>
#define ffor(i,a,b) for(int i=(a) ;i<=(b) ;i++)
#define rrep(i,a,b) for(int i=(a) ;i>=(b) ;i--)
#define mst(v,s) memset(v,s,sizeof(v))
#define IOS ios::sync_with_stdio(false),cin.tie(0)
#define ll long long
#define INF 0x7f7f7f7f7f7f7f7f
#define inf 0x7f7f7f7f
#define PII pair<int,int>
#define int long long

using namespace std;

const int N = 5e5 + 5;
int n, T = 1, m, ai;
double sum[N], a[N], avgsum;

void ready()
{
    int cnt = 1;
    double avg = 0, avgsum = 0;
    cin >> n;
    ffor(i, 1, n) {
        int op;
        cin >> op;
        if (op == 1) {
            cin >> a[++ai];
            sum[ai] = a[ai] + sum[ai - 1]; 
        }
        else {
            avg = (sum[cnt] + a[ai]) / (cnt + 1); 
            while (cnt + 1 < ai && (sum[cnt + 1] + a[ai]) / (cnt + 2)  <= avg) {
                cnt++; 
                avg = (sum[cnt] + a[ai]) / (cnt + 1);
            } 
            double ans = a[ai] - avg;
            printf("%.10lf\n", ans);
        }
    }
}


void work() {

}


signed main()
{
   // IOS;
    ready();
    //cin>>T;
    while (T--) {
        work();
    }
    return 0;
}





Problem J

出处

Codeforces-734D

题解

注意,存在黑Queen。

保存白Queen的八个方向距离它最近的黑棋是什么类型。如果能被吃则Yes。

代码


// Good Good Study, Day Day AC.
#include <iostream>
#include <stdio.h>
#include <cstdio>
#include <stdlib.h>
#include <string>
#include <string.h>
#include <cstring>
#include <math.h>
#include <cmath>
#include <queue>
#include <deque>
#include <stack>
#include <vector>
#include <map>
#include <algorithm>
#include <unordered_map>
#include <unordered_set>
#define ffor(i,a,b) for(int i=(a) ;i<=(b) ;i++)
#define rrep(i,a,b) for(int i=(a) ;i>=(b) ;i--)
#define mst(v,s) memset(v,s,sizeof(v))
#define IOS ios::sync_with_stdio(false),cin.tie(0)
#define ll long long
#define INF 0x7f7f7f7f7f7f7f7f
#define inf 0x7f7f7f7f
#define PII pair<int,int>
#define int long long

using namespace std;

int n, T = 1, m;
int qx, qy;

char lu = '0', ru = '0', ld = '0', rd = '0', u = '0', d = '0', l = '0', r = '0';
int dlu, dru, dld, drd, du, dd, dl, dr;

bool check_(PII a, PII b) {
    int ax = a.first, ay = a.second, bx = b.first, by = b.second, cx = qx, cy = qy;
    return ((by - ay) * (cx - bx) == (cy - by) * (bx - ax));
}

int dis(PII a, PII b) {
    int ax = a.first, ay = a.second, bx = b.first, by = b.second;
    return (by - ay) * (by - ay) + (bx - ax) * (bx - ax);
}

void ready()
{
    cin >> n >> qx >> qy;
    ffor(i, 1, n) {
        char ch;
        int dister;
        int x, y;
        cin >> ch >> x >> y;
        PII item = { x,y }, queen = { qx,qy };
        dister = dis(item, queen);
        if (check_(item, { qx - 1,qy + 1 }) && x < qx) {
            if (!dlu || dlu > dister) {
                dlu = dister;
                lu = ch;
            }
        }
        if (check_(item, { qx - 1,qy - 1 }) && x < qx) {
            if (!dld || dld > dister) {
                dld = dister;
                ld = ch;
            }
        }
        if (check_(item, { qx + 1,qy + 1 }) && x > qx) {
            if (!dru || dru > dister) {
                dru = dister;
                ru = ch;
            }
        }
        if (check_(item, { qx + 1,qy - 1 }) && x > qx) {
            if (!drd || drd > dister) {
                drd = dister;
                rd = ch;
            }
        }
        if (x == qx) {
            if (y > qy) {
                if (!du || du > dister) {
                    du = dister;
                    u = ch;
                }
            }
            if (y < qy) {
                if (!dd || dd > dister) {
                    dd = dister;
                    d = ch;
                }
            }
        }
        if (y == qy) {
            if (x > qx) {
                if (!dr || dr > dister) {
                    dr = dister;
                    r = ch;
                }
            }
            if (x < qx) {
                if (!dl || dl > dister) {
                    dl = dister;
                    l = ch;
                }
            }
        }
    }
}



bool work()
{
    if (l == 'Q' || l == 'R' || r == 'Q' || r == 'R' || u == 'Q' || u == 'R' || d == 'Q' || d == 'R') return true;
    if (ld == 'Q' || ld == 'B' || lu == 'Q' || lu == 'B' || rd == 'Q' || rd == 'B' || ru == 'Q' || ru == 'B') return true;
    return false;
}

signed main()
{
    IOS;
    ready();
    //cin>>T;
    while (T--) {
        if (work()) cout << "YES";
        else cout << "NO";
    }
    return 0;
}





  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值