GDKOI 2021 Day3 PJ 懵逼记

今天早了一点起来,初三的大奆都来做比赛了,
自然,自测的有许多 AK
虽然今天的题比昨天简单,但还是脑子还是十分迟钝,以至于贪心都想不出
真为明天的提高组而担忧

T1

斜率被卡 90 ,直接用勾股定理判断边的放大比例是否相等,注意可以不开方

#include<bits/stdc++.h>
using namespace std;
const double eps=1e-7;
typedef long long LL;
int T;
LL z1[5],x[10],y[10],z2[5],gg;
inline LL Dis(int p,int q) {
	return (x[p]-x[q])*(x[p]-x[q])+(y[p]-y[q])*(y[p]-y[q]);
}
inline LL Gcd(LL p,LL q) {
	return q?Gcd(q,p%q):p;
}
inline bool Chk() {
	if(z1[1]!=z1[2]||z2[1]!=z2[2])return false;
	if(z1[1]!=z1[3]||z2[1]!=z2[3])return false;
	if(z1[2]!=z1[3]||z2[2]!=z2[3])return false;
	return true;
}
int main() {
	freopen("triangle.in","r",stdin);
	freopen("triangle.out","w",stdout);
	scanf("%d",&T);
	while(T--) {
		for(int i=1;i<7;i++)scanf("%lld%lld",&x[i],&y[i]);
		z1[1]=Dis(1,2),z1[2]=Dis(1,3),z1[3]=Dis(2,3);
		z2[1]=Dis(4,5),z2[2]=Dis(4,6),z2[3]=Dis(5,6);
		sort(z1+1,z1+4),sort(z2+1,z2+4);
		gg=Gcd(z1[1],z2[1]),z1[1]/=gg,z2[1]/=gg;
		gg=Gcd(z1[2],z2[2]),z1[2]/=gg,z2[2]/=gg;
		gg=Gcd(z1[3],z2[3]),z1[3]/=gg,z2[3]/=gg;
		if(Chk())puts("YES");
		else puts("NO");
	}
}

T2

贪心,由于比 x 排名高的只有\(\sum_{j=1}^i r_j-1\)个,考虑用贪心

  1. 最优,比 x 高的都是 100 ,比 x 低的都是 0 , x 是 99.99999 ,即无限接近 100
    只要有一个科排名低于 x 就比 x 分数低
    \(sum\le (n-1)(i-1)\) 排名为 1 ,否则为 \(sum+1-(n-1)(i-1)\)
  2. 最坏,比 x 高的都是 100 ,比 x 低的都是 0 , x 是 0.000001 ,即无限接近 0
    只要有一个科排名高于 x 就比 x 分数高
    \(sum\ge n-1\) 排名为 n ,否则为 \(sum+1\)
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
int m;
LL n,sm;
int main() {
	scanf("%lld%d",&n,&m);
	for(int i=1,x;i<=m;i++) {
		scanf("%d",&x);
		sm+=1LL*x-1LL;
		if(sm<=1LL*(n-1)*(i-1))printf("1 ");
		else printf("%lld ",sm-1LL*(n-1)*(i-1)+1);
		if(sm>=n-1)printf("%lld\n",n);
		else printf("%lld\n",sm+1);
	}
}

T3

\(sum(x)=\sum_{i|x}\lambda(i),n=\Pi\ p_i^{e_i}\) ,若 \(e_k\) 有一个是奇数,则\(sum(x)\)可以抵消
否则,就是完全平方数,直接算出其个数还有其倍数的个数累加即可

#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const LL mod=998244353;
LL n,ans;
int main() {
//	freopen("number.in","r",stdin);
//	freopen("number.out","w",stdout); 
	scanf("%lld",&n);
	for(LL i=1;i<=sqrt(n);i++)
		ans+=n/(i*i),ans>=mod?ans-=mod:1;
	printf("%lld",ans);
}

T4

设 F[i][j] 为左右都到 i 的前后差为 j 的方案,发现只用枚举 \(\lfloor \frac{n}{2}\rfloor\) 就行了\(F_{0,1}=1,i\in [1,\lfloor \frac{n}{2}\rfloor],j\in [1,n*n] F_{i,j}=\sum_{k=\max(j-n,0)}^{j+n} F_{i-1,k}*(n+1-|j-k|)\)
最后答案是 \(\sum_{j=1}^{n*n} F_{\lfloor \frac{n}{2}\rfloor,j}\)
若 n 是奇数,答案要乘 n+1 ,因为 \(\lfloor \frac{n+1}{2}\rfloor\) 可以放 0~n

#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const LL mod=998244353;
int n,m;
LL ans,f[105][20005];
int main() {
	freopen("sequence.in","r",stdin);
	freopen("sequence.out","w",stdout);
	scanf("%d",&n);
	m=n*n+1,f[0][1]=1;
	for(int i=1;i<=(n>>1);i++)
		for(int j=1;j<=m;j++)
			for(int k=max(j-n,0);k<=j+n;k++)
				f[i][j]+=f[i-1][k]*(n+1-abs(j-k)),f[i][j]%=mod;
	for(int i=1;i<=m;i++)ans+=f[n>>1][i],ans%=mod;
	if(n&1)ans=ans*(n+1)%mod;
	printf("%lld",ans);
}

End

GDKOI 都是思维题,本蒟蒻的思维还是要多加磨炼

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值