首页 > 其他分享 >AtCoder Beginner Contest 280 题解

AtCoder Beginner Contest 280 题解

时间:2022-12-03 23:11:25浏览次数:60  
标签:AtCoder int 题解 make long pair 280 my define

A - Pawn on a Grid

看样例猜题意(

要求的是 # 的数量,直接判断。

//If, one day, I finally manage to make my dreams a reality...
//I wonder, will you still be there by my side?
#include<bits/stdc++.h>
#define IOS ios::sync_with_stdio(false)
#define TIE cin.tie(0),cout.tie(0)
#define int long long
#define y1 cyy
#define fi first
#define se second
#define cnt1(x) __builtin_popcount(x)
#define mk make_pair
#define pb push_back
#define pii pair<int,int>
#define ls(x) (x<<1)
#define rs(x) (x<<1|1)
#define lbt(x) (x&(-x))
using namespace std;
int n,m,ans;
char c;
signed main(){
	IOS;TIE;
	cin>>n>>m;
	for(int i=1;i<=n;i++){
		for(int j=1;j<=m;j++){
			cin>>c;
			if(c=='#') ans++;
		}
	}
	cout<<ans<<endl;
	return 0;
}

B - Inverse Prefix Sum

看样例猜题意*2

直接输出差分数组就好了。

//If, one day, I finally manage to make my dreams a reality...
//I wonder, will you still be there by my side?
#include<bits/stdc++.h>
#define IOS ios::sync_with_stdio(false)
#define TIE cin.tie(0),cout.tie(0)
#define int long long
#define y1 cyy
#define fi first
#define se second
#define cnt1(x) __builtin_popcount(x)
#define mk make_pair
#define pb push_back
#define pii pair<int,int>
#define ls(x) (x<<1)
#define rs(x) (x<<1|1)
#define lbt(x) (x&(-x))
using namespace std;
int n,a[200005];
signed main(){
	IOS;TIE;
	cin>>n;
	for(int i=1;i<=n;i++) cin>>a[i];
	for(int i=1;i<=n;i++) cout<<a[i]-a[i-1]<<' ';
	cout<<endl;
	return 0;
}

C - Extra Character

两个字符串第一个不同位置加一个一定是合法的。正确性显然。

//If, one day, I finally manage to make my dreams a reality...
//I wonder, will you still be there by my side?
#include<bits/stdc++.h>
#define IOS ios::sync_with_stdio(false)
#define TIE cin.tie(0),cout.tie(0)
#define int long long
#define y1 cyy
#define fi first
#define se second
#define cnt1(x) __builtin_popcount(x)
#define mk make_pair
#define pb push_back
#define pii pair<int,int>
#define ls(x) (x<<1)
#define rs(x) (x<<1|1)
#define lbt(x) (x&(-x))
using namespace std;
string s,t;
signed main(){
	IOS;TIE;
	cin>>s>>t;
	for(int i=0;i<t.size();i++){
		if(s[i]!=t[i]){
			cout<<i+1<<endl;
			return 0;
		}
	}
	return 0;
}

D - Factorial and Multiple

一开始傻掉萎了两发(

直接二分答案就好,二分答案为 \(x\) 的阶乘。

如何判断 \(x\) 是否合法?设 \(cnt_{p_i}\) 为原来的 \(k\) 所含质因数 \(p_i\) 的数量,显然需要 \(1\sim x\) 中所有数分解质因数后每一个 \(p_i\) 的数量之和都 \(>cnt_{p_i}\)。

考虑如何快速计算 \(1\sim x\) 中各质因数数量之和。设要求的质因数为 \(p_i\),则 \(1\sim x\) 中质因数 含一个及以上 \(p_i\) 的数的数量为 \(\lfloor\frac x {p_i}\rfloor\),含两个及以上 \(p_i\) 的数的数量为 \(\lfloor\frac x {{p_i}^2}\rfloor\),含三个及以上 \(p_i\) 的数的数量为 \(\lfloor\frac x {{p_i}^3}\rfloor\),以此类推。

然后就做完了。

//If, one day, I finally manage to make my dreams a reality...
//I wonder, will you still be there by my side?
#include<bits/stdc++.h>
#define IOS ios::sync_with_stdio(false)
#define TIE cin.tie(0),cout.tie(0)
#define int long long
#define y1 cyy
#define fi first
#define se second
#define cnt1(x) __builtin_popcount(x)
#define mk make_pair
#define pb push_back
#define pii pair<int,int>
#define ls(x) (x<<1)
#define rs(x) (x<<1|1)
#define lbt(x) (x&(-x))
using namespace std;
int k,n;
map<int,int> mp,mp2;
bool check(int mid){
	for(auto i:mp){
		int cnt=0,tmp=i.fi;
		while(tmp<=mid) cnt+=mid/tmp,tmp*=i.fi;
		if(cnt<i.se) return 0;
	}
	return 1;
}
signed main(){
	IOS;TIE;
	cin>>k;
	int l=1,r=k,ans;
	for(int i=2;i*i<=k;i++){
		while(k%i==0) mp[i]++,k/=i;
	}
	if(k>1) mp[k]++;
	while(l<=r){
		int mid=(l+r)>>1;
		if(check(mid)) r=mid-1,ans=mid;
		else l=mid+1;
	}
	cout<<ans<<endl;
	return 0;
}

E - Critical Hit

最基础的概率 \(\text{DP}\)。考虑记 \(f_i\) 表示使怪物血量降低至 \(i\) 的期望攻击次数。同时因为给出的 \(p\) 不是实际概率,实际概率为 \(p\div 100\),每次写逆元比较麻烦,所以事先算好 \(E=100^{mod-2}\),这样 \(\div 100\) 时只要 \(\times E\) 即可。

初始 \(f_n=0\),然后倒序枚举。每个值的贡献由扣两点血和扣一点血组成:

  • 扣两点血( i=n-1 时只能照扣一点算):

\[f_i=f_i+(f_{i+1+(i!=n-1)}+1)\times p\times E \]

  • 扣一点血:

\[f_i=f_i+(f_{i+1}+1)\times(1-p\times E) \]

最后输出 \(f_0\) 即可。

//If, one day, I finally manage to make my dreams a reality...
//I wonder, will you still be there by my side?
#include<bits/stdc++.h>
#define IOS ios::sync_with_stdio(false)
#define TIE cin.tie(0),cout.tie(0)
#define int long long
#define y1 cyy
#define fi first
#define se second
#define cnt1(x) __builtin_popcount(x)
#define mk make_pair
#define pb push_back
#define pii pair<int,int>
#define ls(x) (x<<1)
#define rs(x) (x<<1|1)
#define lbt(x) (x&(-x))
#define mod 998244353
using namespace std;
int n,p,f[200005];
int ksm(int x,int b){
	int ans=1;
	while(b){
		if(b&1) ans=ans*x%mod;
		x=x*x%mod;
		b>>=1;
	}
	return ans;
}
signed main(){
	IOS;TIE;
	cin>>n>>p;
	int E=ksm(100,mod-2);
	f[n]=0;
	for(int i=n-1;i>=0;i--){
		f[i]+=(f[i+1+(i!=n-1)]+1)*p%mod*E%mod,f[i]%=mod;
		f[i]+=(f[i+1]+1)*(1-p*E%mod)%mod,f[i]%=mod;
		f[i]+=mod,f[i]%=mod;
	}
	cout<<f[0]<<endl;
	return 0;
}

F - Pay or Receive

智慧题。赛时贺了个带权并查集,后来发现直接 \(\text{DFS}\) 似乎更简单?

大题思路差不多。

首先是 nan 的情况,只需判断两点是否在同一连通块中即可。

然后是 inf 的情况。不难发现路径要无限长只能是出现了 \(>0\) 的环,这样的话环所在的整个连通块中,任意两点之间都是 inf。考虑如何判断这样的正环。首先按题意建图,然后在每个连通块内跑一遍 \(\text{DFS}\) 搞出一颗生成树并记下到每个点的距离。若没有正环,则初始连边的距离是和生成树跑出来的距离相等的。换句话说,两点间怎么走距离都是相等的。然后只要给出现距离矛盾的点所在的连通块都打上标记即可。

剩下的直接用生成树跑出来的距离算。

//If, one day, I finally manage to make my dreams a reality...
//I wonder, will you still be there by my side?
#include<bits/stdc++.h>
#define IOS ios::sync_with_stdio(false)
#define TIE cin.tie(0),cout.tie(0)
#define int long long
#define y1 cyy
#define fi first
#define se second
#define cnt1(x) __builtin_popcount(x)
#define mk make_pair
#define pb push_back
#define pii pair<int,int>
#define ls(x) (x<<1)
#define rs(x) (x<<1|1)
#define lbt(x) (x&(-x))
#define mod 998244353
using namespace std;
int n,m,q,u,v,w,col[100005],cnt,f[100005];
bool mark[100005],vis[100005];
struct node{
	int to,dis;
};
vector<node> a[100005];
void dfs(int x,int c){
	col[x]=c,vis[x]=1;
	for(int i=0;i<a[x].size();i++){
		node tmp=a[x][i];
		if(!vis[tmp.to]){
			f[tmp.to]=f[x]+tmp.dis;
			dfs(tmp.to,c);
		}
	}
}
signed main(){
	IOS;TIE;
	cin>>n>>m>>q;
	for(int i=1;i<=m;i++){
		cin>>u>>v>>w;
		a[u].push_back({v,w}),a[v].push_back({u,-w});
	}
	for(int i=1;i<=n;i++){
		if(!vis[i]) dfs(i,++cnt);
	}
	for(int i=1;i<=n;i++){
		for(int j=0;j<a[i].size();j++){
			node tmp=a[i][j];
			if(f[tmp.to]!=f[i]+tmp.dis) mark[col[i]]=1;
		}
	}
	while(q--){
		cin>>u>>v;
		if(col[u]!=col[v]) cout<<"nan"<<endl;
		else if(mark[col[u]]) cout<<"inf"<<endl;
		else cout<<f[v]-f[u]<<endl;
	}
	return 0;
}

也附上带权并查集的代码:

//If, one day, I finally manage to make my dreams a reality...
//I wonder, will you still be there by my side?
#include<bits/stdc++.h>
#define IOS ios::sync_with_stdio(false)
#define TIE cin.tie(0),cout.tie(0)
#define int long long
#define y1 cyy
#define fi first
#define se second
#define cnt1(x) __builtin_popcount(x)
#define mk make_pair
#define pb push_back
#define pii pair<int,int>
#define ls(x) (x<<1)
#define rs(x) (x<<1|1)
#define lbt(x) (x&(-x))
#define mod 998244353
using namespace std;
int n,m,q,u,v,w,fa[200005],f[200005];
bool mark[200005];
int find(int x){
	if(x==fa[x]) return x;
	int tmp=fa[x];
	fa[x]=find(fa[x]);
	f[x]+=f[tmp];
	return fa[x];
}
void merge(int x,int y,int fx,int fy,int k){
	fa[fx]=fy;
	f[fx]=f[y]+k-f[x];
	mark[fy]|=mark[fx];
}
signed main(){
	IOS;TIE;
	cin>>n>>m>>q;
	for(int i=1;i<=n;i++) fa[i]=i;
	for(int i=1;i<=m;i++){
		cin>>u>>v>>w;
		int fx=find(u),fy=find(v);
		if(fx^fy) merge(u,v,fx,fy,w);
		else if(f[u]^(f[v]+w)) mark[fx]=1;
	}
	while(q--){
		cin>>u>>v;
		int fx=find(u),fy=find(v);
		if(fx^fy) cout<<"nan"<<endl;
		else if(mark[fx]) cout<<"inf"<<endl;
		else cout<<f[u]-f[v]<<endl;
	}
	return 0;
}

标签:AtCoder,int,题解,make,long,pair,280,my,define
From: https://www.cnblogs.com/binary1110011/p/16948999.html

相关文章

  • YACS 2022年11月月赛 乙组 T3 菜单设计 题解
    题目链接上完编程课回来的深夜,更一篇吧。这一题一看数据范围$:18$,阶乘暴力打不了,就是状压。其实我还是比较喜欢状压的,不过这几个月怎么这么多状压?首先:设计状态不难发......
  • AtCoder Beginner Contest 280 D-E
    D-FactorialandMultiple前置知识\(n!\)中包含素因子\(p\)的个数为\[cnt=\sum\limits_{k\geq1}^{p^k\leqn}\lfloor\frac{n}{p^k}\rfloor\]例如:\(n!\)......
  • 树上染色-题解(贪心+DP+二分)
    树的上色题意简述树上有两个黑点,在每个单位时间内,每个黑点可以把自己相邻的一个白点变为黑色,求把整棵树所有点变为黑色的最短时间。\(n\)个点,两个黑点分别为\(x,y\)。......
  • 2022合肥学院acm程序设计大赛-热身赛题解 (1)
    A.codeforces直接读入输入即可#include<bits/stdc++.h>intmain(){strings;cin>>s;cout<<"https://codeforces.com/profile/"<<s;return0;}......
  • 合肥学院校赛热身赛题解
    A.codeforces直接读入输入即可#include<bits/stdc++.h>intmain(){strings;cin>>s;cout<<"https://codeforces.com/profile/"<<s;return0;}......
  • [SCOI2014]方伯伯的玉米田题解
    [SCOI2014]方伯伯的玉米田题目描述方伯伯在自己的农田边散步,他突然发现田里的一排玉米非常的不美。这排玉米一共有\(N\)株,它们的高度参差不齐。方伯伯认为单调不下降序......
  • Ynoi2011题解
    d1t1初始化题意一个长度为\(n\)的序列,\(q\)次操作。询问\([l,r]\)的区间和。将所有\(\bmodx=y\)的下标位置加\(z\)。\(n,q\leq2\times10^5\)。题解......
  • CF1710 题解
    比赛链接:https://codeforces.com/contest/1711BD比以往的要难,E要更简单A水题//bySkyRainWind#include<cstdio>#include<vector>#include<cassert>#include<c......
  • 问题解决系列:从源码讲解为什么是 'JZ0SL_ Unsupported SQL type 1111'
    一、问题场景正在做代码改造,使用​​mybatis​​​+​​sybase​​进行数据库操作,运行过程中,提示以下报错:java.io.IOException:JZ0SL:UnsupportedSQLtype1111.本篇博客......
  • ORA-28040: 没有匹配的验证协议
    问题:ORA-28040:没有匹配的验证协议原因:Oracle数据库安装的是12.2版本,OracleClient安装的版本是11(ODTwithODAC1120320_32bit)。解决:打开 sqlnet.ora 文件,增加以下两行......