2023.11.08

发布时间 2023-11-09 09:43:44作者: shyiaw

T1

题面

image

解题

  1. 发现整个队伍的速度可以二分。若整个队伍的速度可以达到 \(x_0\),则对任意小于 \(x_0\) 的速度均可被满足;若整个队伍的速度不可以达到 \(x_0\),则任意大于 \(x_0\) 的速度均无法达到(若不然,整个队伍的速度可以满足 \(x_0\))。
  2. 考虑如何检验速度 \(x_0\) 是否可以达到。将所有成员分为两堆:速度大于等于 \(x_0\) 的成员(可以用来带人)与速度小于 \(x_0\) 的成员(需要被待)。故可以达到的标志为所有需要被带的成员均可被带。贪心,用带人能力强的成员去带难带的成员,判断是否需要被带的成员是否均可被带。
  3. 时间复杂度为 \(\mathcal O(n\log(\max\{v\}))\)

代码

点击查看代码
#include<bits/stdc++.h>
using namespace std;
const int maxn=1e5+10;
int a[maxn],n,w[maxn];
priority_queue<int,vector<int>,less<int>> q,qi,em;
bool check(int x)
{
	q=em,qi=em;
	for(int i=1;i<=n;i++)
		if(a[i]>=x) q.push(a[i]+w[i]-x);
		else qi.push(w[i]);
	while(!qi.empty())
	{
		if(q.empty()) return false;
		if(q.top()<qi.top()) return false;
		q.pop(),qi.pop();
	}
	return true;
}
void solve()
{
	scanf("%d",&n);
	int ans=0,l=0,r=0;
	for(int i=1;i<=n;i++)
		scanf("%d%d",&a[i],&w[i]),r=max(r,a[i]);
	while(l<=r)
	{
		int mid=(l+r)>>1;
		if(check(mid)) ans=mid,l=mid+1;
		else r=mid-1;
	}
	printf("%d\n",ans);
}
int main()
{
	int t;scanf("%d",&t);
	while(t--) solve();
	return 0;
}

T2

题面

image

解题

  1. 构造题。先以黑方块为中心,向外做正方形拓展(两个 L 叠起来),直到遇见边界 I。发现正方形与垂直于 I 的两个边界的距离之和恒等于正方形到与 I 平行的边界的距离,故恒可被构造。
  2. 时间复杂度为 \(\mathcal O(n)\)

代码

点击查看代码
#include<bits/stdc++.h>
using namespace std;
const int maxn=1e3+10;
int n,bx,by;
bool check(int l,int r,int u,int d)
{
	if(l<=1||l>=n) return false;
	if(r<=1||r>=n) return false;
	if(u<=1||u>=n) return false;
	if(d<=1||d>=n) return false;
	return true;
}
struct node
{
	int r,c,h,w;
	void print()
	{
		printf("%d %d %d %d\n",r,c,h,w);
	}
};
void solve()
{
	printf("Yes\n");
	scanf("%d%d%d",&n,&bx,&by);
	int l=by,r=by,u=bx,d=bx;
	vector<node> ans;
	while(check(l,r,u,d))
	{
		l--,r++,d++,u--;
		int ri,ci,hi,wi;
		int rii,cii,hii,wii;
		ri=d,ci=r,hi=u-d+1,wi=l-r;
		rii=u,cii=l,hii=d-u-1,wii=r-l;
		ans.push_back((node){ri,ci,hi,wi});
		ans.push_back((node){rii,cii,hii,wii});
	}
	//cout<<u<<" "<<d<<" "<<l<<" "<<r<<endl;
	if(u==1)
	{
		int k=1;
		for(int i=l-1;i>0;i--,k++)
		{
			int ri,ci,hi,wi;
			ci=i,ri=d+k;
			hi=1-d-k,wi=r-i;
			ans.push_back((node){ri,ci,hi,wi});
		}
		for(int i=r+1;i<=n;i++,k++)
		{
			int ri,ci,hi,wi;
			ci=i,ri=d+k;
			hi=1-d-k,wi=1-i;
			ans.push_back((node){ri,ci,hi,wi});
		}
	}
	else if(l==1)
	{
		int k=1;
		for(int i=u-1;i>0;i--,k++)
		{
			int ri,ci,hi,wi;
			ri=i,ci=r+k;
			hi=d-ri,wi=1-r-k;
			ans.push_back((node){ri,ci,hi,wi});
		}
		for(int i=d+1;i<=n;i++,k++)
		{
			int ri,ci,hi,wi;
			ri=i,ci=r+k;
			hi=1-ri,wi=1-r-k;
			ans.push_back((node){ri,ci,hi,wi});
		}
	}
	else if(d==n)
	{
		int k=1;
		for(int i=l-1;i>0;i--,k++)
		{
			int ri,ci,hi,wi;
			ci=i,ri=u-k;
			hi=n-ri,wi=r-i;
			ans.push_back((node){ri,ci,hi,wi});
		}
		for(int i=r+1;i<=n;i++,k++)
		{
			int ri,ci,hi,wi;
			ci=i,ri=u-k;
			hi=n-ri,wi=1-i;
			ans.push_back((node){ri,ci,hi,wi});
		}
	}
	else if(r==n)
	{
		int k=1;
		for(int i=u-1;i>0;i--,k++)
		{
			int ri,ci,hi,wi;
			ri=i,ci=l-k;
			hi=d-ri,wi=n-ci;
			ans.push_back((node){ri,ci,hi,wi});
		}
		for(int i=d+1;i<=n;i++,k++)
		{
			int ri,ci,hi,wi;
			ri=i,ci=l-k;
			hi=1-ri,wi=n-ci;
			ans.push_back((node){ri,ci,hi,wi});
		}
	}
	printf("%d\n",ans.size());
	vector<node>::iterator it;
	for(it=ans.begin();it!=ans.end();it++)
	{
		node ansi=*it;
		ansi.print();
	}
}
int main()
{
	int t=1;//scanf("%d",&t);
	while(t--) solve();
	return 0;
}

正解思路

image

正解代码

点击查看代码
#include <bits/stdc++.h>
using namespace std;

int main() {
    int n, i, j; scanf("%d%d%d", &n, &i, &j);
    // UDLR 表示现在包出来的正方形的上下左右边界
    int U = i, D = i;
    int L = j, R = j;
    printf("Yes\n%d\n", n - 1);
    for (int k = 1; k < n; k++) {
        if (U > 1 && L > 1) {
            U--; L--;
            printf("%d %d %d %d\n", U, L, D - U, R - L);
        } else if (U > 1 && R < n) {
            U--; R++;
            printf("%d %d %d %d\n", U, R, D - U, L - R);
        } else if (D < n && L > 1) {
            D++; L--;
            printf("%d %d %d %d\n", D, L, U - D, R - L);
        } else {
            D++; R++;
            printf("%d %d %d %d\n", D, R, U - D, L - R);
        }
    }
    return 0;
}