牛客竞赛,ZUST第17届公开赛,摸鱼记(A、DEFGH、J题解,3/7题代码)

碎碎念

我快两点了才想起来下午比赛
一个多小时写了五份就签上两题的道
然后一直在调那个chess,优化搜索…
快结束了才意识到可以打表

好多题都只能过样例
合并序列,枚举k,暴力统计不知道为啥会WA,题意里的k到底代表什么意思至今没看懂。。。
tree我感觉暴力枚举c(n,2)加lca大概lgn应该是可以卡5e5的数据的啊,可是怎么调都TLE

A The warm love problem AC

题意:给出桌子的四只脚,判断能否放置一个矩形桌面在上面
这个结论有点猜测的意味,,不过一遍就过了也没花多少时间

//四点在一个矩形面上
//四个数排序,间距为1,判断是否能构成平行四边形,会不会WA?,过了就好。。。
#include
#include
#include
using namespace std;
int a[5];
struct point{
      double x, y; }pp[4];
double TwoPointDiatance(point a, point b){
     //计算两点之间的距离
	return sqrt(pow((a.x - b.x), 2) + pow((a.y - b.y), 2));
}
int main(){
     
	int T;  cin>>T;
	while(T--){
     
		for(int i = 1; i <= 4; i++)cin>>a[i];
		sort(a+1,a+5);
		int ok = 1;
		for(int i = 2; i <= 4; i++)
			if(a[i]!=a[1]){
     ok=0;break;}
		if(ok){
     
			cout<<"YES\n";
			continue;
		}
		//
		for(int i = 1 ; i <= 4; i++){
     
			pp[i].x = (double)i;   pp[i].y = (double)a[i];
		}
		double s1, s2, s3, s4;
		s1 = TwoPointDiatance(pp[1], pp[3]);
		s2 = TwoPointDiatance(pp[1], pp[2]);
		s3 = TwoPointDiatance(pp[4], pp[2]);
		s4 = TwoPointDiatance(pp[3], pp[4]);
		if(s1==s3 && s2==s4 && s1!=0){
     
			cout<<"YES\n";
			continue;
		}
		cout<<"NO\n";
	}
	return 0;
}

D 合并序列 WA

拿到题面的想法就是合并果子小根堆小根堆,然后直接枚举嘿嘿
TLE也就认了,,WA是什么鬼。。
别看了我没过。。
题解貌似让我长点脑子,,二分一下就可以小根堆了。。
牛客竞赛,ZUST第17届公开赛,摸鱼记(A、DEFGH、J题解,3/7题代码)_第1张图片

//对于给定的k最小代价,类似于合并果子,小根堆维护
//枚举k,暴力统计,会不会TLE
#include
#include
#include
using namespace std;
//priority_queue, greater >q;
vector<int>v;
int main(){
     
    int n, T;
	cin>>n>>T;
	for(int i = 1; i <= n ; i++){
     
		int x;  cin>>x;  v.push_back(x);
	}
	int ansk = n;
	for(int kk = 2; kk <= n; kk++){
     
		priority_queue<int, vector<int>, greater<int> >q;
		for(int i = 0; i < n; i++)q.push(v[i]);
		int num = 0;
		for(int i = 0; i < n; i++){
     
			int tmp = 0;
			for(int j = 1; j <= kk; j++){
     
				tmp += q.top();  q.pop();
				if(q.size()==0)break;
			}
			//cout<<" "<
			num += tmp;
			q.push(tmp);
			if(q.size()==1)break;
		}
		//cout<
		if(num<=T){
     
			ansk = kk;
			break;
		}
	}
	cout<<ansk<<"\n";
    return 0;
}

E&F 题解

E感觉很可做,但是题意min(x,tot)没看懂,不知道要求啥
F大概直接是不会做的

牛客竞赛,ZUST第17届公开赛,摸鱼记(A、DEFGH、J题解,3/7题代码)_第2张图片
牛客竞赛,ZUST第17届公开赛,摸鱼记(A、DEFGH、J题解,3/7题代码)_第3张图片
牛客竞赛,ZUST第17届公开赛,摸鱼记(A、DEFGH、J题解,3/7题代码)_第4张图片

牛客竞赛,ZUST第17届公开赛,摸鱼记(A、DEFGH、J题解,3/7题代码)_第5张图片

G chess AC

全场写的最蛋疼的一题,chess爆搜也是人才
开始深搜,记忆化vis二维4e5开不下换成set,甚至想换unordered_set还是一直TLE。
从最开始的枚举n,m二维搜到后来从1,1开始搜。。。
可是吧,感觉题面这么简洁经典的一道题,怎么可能这么奇怪的做法,还unordered_set都出来了。。。

然后我突然意识到,除了一些特殊情况走不满,其他的可以走满,这就是象棋的马走日
我记得马是可以不重复地走满象棋盘,所以应该只有部分小情况不行
什么情况下不行呢,这个就可以暴力了。。
最后搜出来去掉m==1,2,3和n==1,2,3,的情况,全部都是n*m

吐血了,优化了一下午的搜索,最后是个打表题。
我说为什么那么多人都过了,我怎么这么菜。

#include
#include
#include
#include
using namespace std;
int n, m, cnt, ans;
//int vis[45010][45010];
/*
set >vi;
const int dx[] = {-2, -2, 2, 2, -1, -1, 1, 1};
const int dy[] = {-1, 1, -1, 1, -2, 2, -2, 2};
void dfs(int x, int y){
	if(x<1||x>n||y<1||y>m)return ;
	//if(vis[x][y])return ;
	if(vi.count(make_pair(x,y)))return ;
	cnt++;
	//vis[x][y] = 1;
	vi.insert(make_pair(x,y));
	for(int i = 0; i < 8; i++){
		dfs(x+dx[i],y+dy[i]);
	}
}
*/
int main(){
     
	cin>>n>>m;
	if(n==3&&m==3){
     
		cout<<8<<endl;
		return 0;
	}
	if(n==1||m==1){
     
		cout<<1<<endl;
		return 0;
	}
	if(n==2){
     
		int as;
		if(m%2==0)as = m/2;
		else as = (m+1)/2;
		cout<<as<<endl;
		return 0;
		/*
		for(int i = 1; i <= n; i++){
			for(int j = 1; j <= m; j++){
				vi.clear(); cnt = 0;
				dfs(i,j);
				ans = max(ans,cnt);
			}
		}
		cout<
	}
	if(m==2){
     
		int as;
		if(n%2==0)as = n/2;
		else as = (n+1)/2;
		cout<<as<<endl;
		return 0;
	}
	cout<<n*m<<endl;
	return 0;
}

H CBX and children AC

题意:大概就是n个小朋友,身高小于1/2的可以躲在高个的后面,求最少看到的人数
直接二分答案了,一圈一个小朋友,,也没花多少时间的样子?(雾)

//5e5的数据大概nlogn而且常数容易卡
//排个序试试二分答案?会TLE吗
#include
#include
using namespace std;
int n, h[500010];
bool cmp(int x, int y){
     return x>y;}
bool check(int x){
     //cbx只找到x个孩子是否成立
	if(x<n-x)return false;
	int ok = 1;
	for(int i = x+1; i <= n; i++){
     
		if(h[i]*2>h[i-x]){
     
			ok = 0; break;
		}
	}
	//cout<
	if(ok)return true;
	else return false;
}
int main(){
     
	cin>>n;
	for(int i = 1; i <= n; i++)cin>>h[i];
	sort(h+1,h+n+1,cmp);
	int l = 1, r = n;
	while(l < r){
     
		int mid = l+r>>1;
		if(check(mid))r = mid;
		else l = mid+1;
	}
	//cout<
	cout<<l<<'\n';
	return 0;
}

J Tree TLE

牛客竞赛,ZUST第17届公开赛,摸鱼记(A、DEFGH、J题解,3/7题代码)_第6张图片

//LCA求树上路径logn,枚举方案C(n,2),2e5的数据应该能卡吧
#include
#include
#include
#include
#define maxn 200010
using namespace std;

int n,q;
struct edge{
      int next,v; }edges[maxn*2];
int cnt, head[maxn];
void init(){
      memset(head,-1,sizeof(head)); cnt=0; }
void addedge(int u,int v){
     
    edges[cnt].next=head[u];
    edges[cnt].v=v;
    head[u]=cnt++;
}

int dep[maxn];
int f[maxn][21];
void dfs(int u, int fa){
     
	dep[u] = dep[fa]+1;
	for(int i = 0; i <= 19; i++)
		f[u][i+1]=f[f[u][i]][i];
	for(int i = head[u]; i != -1; i = edges[i].next){
     
		int v = edges[i].v;
		if(v==fa)continue;
		f[v][0] = u;
		dfs(v,u);
	}
}
int lca(int x, int y){
     
	if(dep[x]<dep[y])swap(x,y);
	for(int i = 20; i >= 0; i--){
     
		if(dep[f[x][i]]>=dep[y])x=f[x][i];
		if(x==y)return x;
	}
	for(int i = 20; i >= 0; i--){
     
		if(f[x][i]!=f[y][i]){
     
			x = f[x][i];
			y = f[y][i];
		}
	}
	return f[x][0];
}

int m, a[maxn], b[maxn];

int main(){
     
	scanf("%d%d",&n,&m);
	init();
	for(int i = 1; i <= n-1; i++){
     
		int x, y;  scanf("%d%d",&x,&y);
		addedge(x,y);  addedge(y,x);
	}
	dfs(1,0);
	for(int i = 1; i <= m; i++){
     
		scanf("%d%d",&a[i],&b[i]);
	}
	int ans = 0;
	for(int i = 1; i <= m; i++){
     
		for(int j = i+1; j <= m; j++){
     
			int tmp1 = dep[a[i]]+dep[a[j]]-2*dep[lca(a[i],a[j])];
			int tmp2 = dep[b[i]]+dep[b[j]]-2*dep[lca(b[i],b[j])];
			ans = max(ans, tmp1+tmp2);
		}
	}
	cout<<ans<<"\n";
	return 0;
}


补全BC、I、K

C题考试没时间看了,结束看了题面感觉很可做,但是没时间了
B题又臭又长的英文题再见。
I题又臭又长的英文题再见。
K题题又臭又长的英文题再见。
牛客竞赛,ZUST第17届公开赛,摸鱼记(A、DEFGH、J题解,3/7题代码)_第7张图片
牛客竞赛,ZUST第17届公开赛,摸鱼记(A、DEFGH、J题解,3/7题代码)_第8张图片
牛客竞赛,ZUST第17届公开赛,摸鱼记(A、DEFGH、J题解,3/7题代码)_第9张图片

你可能感兴趣的:(算法)