ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

ABC246 简要题解

2022-04-02 23:04:41  阅读:177  来源: 互联网

标签:简要 return cnt1 int 题解 mid cnt2 ABC246 ans


A

由题意模拟,在已知的 \(3\) 个点中仅出现 \(1\) 次的横坐标即为缺失的那个,纵坐标同理。

int a,b,c,d,e,f,x,y;
map<int,int> cnt1,cnt2;
signed main(){
	cin>>a>>b>>c>>d>>e>>f;
	++cnt1[a],++cnt1[c],++cnt1[e];
	++cnt2[b],++cnt2[d],++cnt2[f];
	if(cnt1[a]==1) x=a;
	if(cnt1[c]==1) x=c;
	if(cnt1[e]==1) x=e;
	if(cnt2[b]==1) y=b;
	if(cnt2[d]==1) y=d;
	if(cnt2[f]==1) y=f;
	cout<<x<<" "<<y;
	return 0;
}

B

由题意计算。

double a,b,c;
signed main(){
	a=(double)read(),b=(double)read();
	c=sqrt(a*a+b*b);
	printf("%.7lf %.7lf",a/c,b/c);
	return 0;
}

C

除了当前 \(a_i<x\) 时对其执行一次操作会使总代价减少 \(a_i\),此外执行 \(t\) 次操作就会使总代价减去 \(t\times x\)。那么优先执行完这部分操作,然后按 \(a\) 的大小降序执行。

int n;
ll a[200005],k,x,sum,s;
signed main(){
	n=read(); k=read(); x=read();
	for(rg int i=1;i<=n;++i) a[i]=read(),sum+=a[i]/x,s+=a[i],a[i]%=x;
	if(sum>=k) return 0*printf("%lld",s-k*x);
	k-=sum; s-=sum*x;
	sort(a+1,a+1+n);
	for(rg int i=n;i>=1&&k;--i) --k,s-=a[i];
	printf("%lld",s);
	return 0;
}

D

枚举 \(a\),将 \(a\) 看作参数,对 \(b\) 求偏导 \(f'(b)=3b^2+2ab+a^2\),\(a,b\) 非负时 \(f'(b)\) 始终非负,因此 \(f(b)\) 单增,于是二分 \(b\) 即可。

ull x,ans=-1;
signed main(){
	cin>>x;
	for(rg ull a=0;a<=1000000;++a){
		ull l=0,r=a;
		while(l<r){
			const ull mid=(l+r)/2ull;
			if(a*a*a+a*a*mid+a*mid*mid+mid*mid*mid>=x) r=mid;
			else l=mid+1;
		}
		const ull mid=l,v=a*a*a+a*a*mid+a*mid*mid+mid*mid*mid;
		if(v>=x) ans=min(ans,v);
	}
	cout<<ans;
	return 0;
}

E

根根据走的方向建分层图,同层代价为 \(0\),跨层代价为 \(1\),根据象棋规则 01bfs 即可。

int n,ax,ay,bx,by,ans[2005][2005][4];
char s[2005][2005];
deque<pair<pii,int> > q;
int dx[]={1,1,-1,-1},dy[]={1,-1,1,-1};
inline pair<pii,int> mp(int a,int b,int c){ return mkp(mkp(a,b),c); }
signed main(){
	cin>>n>>ax>>ay>>bx>>by;
	for(rg int i=1;i<=n;++i){
		scanf("%s",s[i]+1);
		for(rg int j=1;j<=n;++j){
			s[i][j]=(s[i][j]=='.');
			for(rg int k=0;k<4;++k) ans[i][j][k]=inf;
		}
	}
	for(rg int k=0;k<4;++k) q.push_back(mp(ax,ay,k)),ans[ax][ay][k]=1;
	while(!q.empty()){
		const int x=q.front().fi.fi,y=q.front().fi.se,d=q.front().se; q.pop_front();
		for(rg int k=0;k<4;++k){
			if(k==d) continue;
			const int tx=x+dx[k],ty=y+dy[k];
			if(s[tx][ty]&&ans[tx][ty][k]>ans[x][y][d]+1) ans[tx][ty][k]=ans[x][y][d]+1,q.push_back(mp(tx,ty,k)); 
		}
		const int tx=x+dx[d],ty=y+dy[d];
		if(s[tx][ty]&&ans[tx][ty][d]>ans[x][y][d]) ans[tx][ty][d]=ans[x][y][d],q.push_back(mp(tx,ty,d)); 
	}
	const int mn=*min_element(ans[bx][by],ans[bx][by]+4);
	printf("%d",(mn==inf)?-1:mn);
	return 0;
}

F

相当于求并集,考虑容斥,而 \(n\) 很小,可直接枚举钦定必须包含于哪些串中;对于有 \(k\) 个可供使用的字符,那么方案数即为 \(k^L\)。

int n,l,ans;
char s[25];
bitset<26> b[25];
signed main(){
	cin>>n>>l; const int S=(1<<n); 
	for(rg int i=1;i<=n;++i){
		scanf("%s",s+1); const int len=strlen(s+1);
		for(rg int j=1;j<=len;++j) b[i][s[j]-'a']=1;
	}
	for(rg int i=1;i<S;++i){
		bitset<26> now; now.set(); int cnt=0;
		for(rg int j=0;j<n;++j) if((i>>j)&1) now&=b[j+1],++cnt;
		if(cnt&1) ans=(ans+ksm(now.count(),l))%djq;
		else ans=(ans-ksm(now.count(),l)+djq)%djq;
	}
	printf("%d",ans);
	return 0;
}

G

假设最后答案为 \(v\),考虑如何实现选到 \(v\) 的过程:设 \(f_{v,x}\) 表示已经走到节点 \(x\),之后能有几个取到 \(v\) 的选择。若 \(a_x=v\) 则为一种方案(已经走到了节点 \(x\),自己是先手,对方已经无法清零 \(x\)),然后只能在 \(subtree_x\) 内选取,此时对方有一次机会将 \(subtree_x\) 内某个值为 \(v\) 的点删掉,那么就可以得到 \(f_{v,x}=\max(0,-1+\sum_{y\in son_x}f_{v,y})+[a_x=v]\)

然后这个 sb 写了线段树合并然后发现答案其实满足满足单调性,将 \(=v\) 的限制换为 \(\geq v\) 的限制后就可以直接二分 \(v\)。

int n,a[200005],f[200005];
vec e[200005];
void dfs(int x,int fa,const int v){
	for(int y:e[x]) if(y!=fa) dfs(y,x,v),f[x]+=f[y];
	f[x]=max(f[x],0),f[x]+=(a[x]>=v);
}
bool calc(int v){ return memset(f,-1,sizeof(f)),dfs(1,0,v),f[1]; }
signed main(){
	n=read();
	for(rg int i=2;i<=n;++i) a[i]=read();
	for(rg int i=1,u,v;i<n;++i) u=read(),v=read(),e[u].epb(v),e[v].epb(u);
	int l=0,r=1000000000;
	while(l<r){
		const int mid=(l+r+1)>>1;
		if(calc(mid)) l=mid;
		else r=mid-1;
	}
	printf("%d",l);
	return 0;
}

Ex

不会,摆烂。

(还真 tm 是 ddp 啊,说好的老外不会科技的呢?)

标签:简要,return,cnt1,int,题解,mid,cnt2,ABC246,ans
来源: https://www.cnblogs.com/tiatto/p/16094657.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有