Codeforces Round 926 (Div. 2)(A~D)

文章目录

A

输出最大值减最小值,或者排序算一下答案

#include <bits/stdc++.h> 
#define int long long
#define rep(i,a,b) for(int i = (a); i <= (b); ++i)
#define fep(i,a,b) for(int i = (a); i >= (b); --i)
#define pii pair<int, int>
#define ll long long
#define db double
#define endl '\n'
#define x first
#define y second
#define pb push_back
#define inf 0x3f3f3f3f*1ll

using namespace std;

void solve()
{
	int n;
	cin>>n;
	vector<int>a(n+1);
	rep(i,1,n){
		cin>>a[i];
	}
	sort(a.begin()+1,a.end());
	int res=0;
	rep(i,2,n){
		res+=a[i]-a[i-1];
	}
	cout<<res<<endl;
}

signed main(){
	ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
//   	freopen("1.in", "r", stdin);
	int _;
	cin>>_;
	while(_--)
	solve();
	return 0;
}

B

B还wa了一发,有点难受一开始推错了,写的太慢了
思路:
考虑对答案能贡献2的放格有多少个。
上面一行 n n n个能对答案贡献 2 2 2,下面一行除了两端的两个都能对答案贡献2
所以一共能贡献2的方格有 2 ∗ n − 2 2 * n-2 2n2
2254e4c951b6f898f04dc50015e3898.jpg

#include <bits/stdc++.h> 
#define int long long
#define rep(i,a,b) for(int i = (a); i <= (b); ++i)
#define fep(i,a,b) for(int i = (a); i >= (b); --i)
#define pii pair<int, int>
#define ll long long
#define db double
#define endl '\n'
#define x first
#define y second
#define pb push_back
#define inf 0x3f3f3f3f*1ll

using namespace std;

void solve()
{
	int n,k;
	cin>>n>>k;
	int num2=2*n-2;
	if(k>2*num2){
		cout<<num2+k-num2*2<<endl;
	}else{
		cout<<k/2+(k%2!=0)<<endl;
	}
}

signed main(){
	ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
//   	freopen("1.in", "r", stdin);
	int _;
	cin>>_;
	while(_--)
	solve();
	return 0;
}

C

c题溢出了中间应该提前结束
推公式
考虑每次的下注如果在这一轮赢得话就要把之前所有输的钱全部赢回来有点类似倍投的思想】
从一1开始,之前的下注总和记为 s u m sum sum
下一轮下注要下 s u m / ( k − 1 ) + 1 sum/(k-1)+1 sum/(k1)+1才能赢钱
中间如果 s u m > a sum>a sum>a的话要提前结束,说明下不到就会没钱了

#include <bits/stdc++.h> 
#define int long long
#define rep(i,a,b) for(int i = (a); i <= (b); ++i)
#define fep(i,a,b) for(int i = (a); i >= (b); --i)
#define pii pair<int, int>
#define ll long long
#define db double
#define endl '\n'
#define x first
#define y second
#define pb push_back
#define inf 0x3f3f3f3f*1ll

using namespace std;

void solve()
{
	int k,x,a;
	cin>>k>>x>>a;
	int sum=0;
	rep(i,1,x){
		if(sum>a){
			cout<<"NO"<<endl;
			return;
		}
		sum+=sum/(k-1)+1;
	}
	if((a-sum)*(k-1)>sum){
		cout<<"YES"<<endl;
	}else{
		cout<<"NO"<<endl;
	}
}

signed main(){
	ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
//   	freopen("1.in", "r", stdin);
	int _;
	cin>>_;
	while(_--)
	solve();
	return 0;
}

D

树形dp思路参考的是b站的一个题解
这题和c题的题目描述感觉都有点抽象很难懂。
题意:让我们求点集的方案数,点集中没有3个点在一条直线。
f [ u ] [ 0 ] : 表示以 u 为根节点的子树中,危险结点数为 0 个的方案总数 f[u][0]:表示以u为根节点的子树中,危险结点数为0个的方案总数 f[u][0]:表示以u为根节点的子树中,危险结点数为0个的方案总数
f [ u ] [ 1 ] : 表示以 u 为根节点的子树中,危险结点数为 1 个的方案总数 f[u][1]:表示以u为根节点的子树中,危险结点数为1个的方案总数 f[u][1]:表示以u为根节点的子树中,危险结点数为1个的方案总数
f [ u ] [ 2 ] : 表示以 u 为根节点的子树中,危险结点数为 2 个的方案总数 f[u][2]:表示以u为根节点的子树中,危险结点数为2个的方案总数 f[u][2]:表示以u为根节点的子树中,危险结点数为2个的方案总数
考虑状态转移
f [ u ] [ 0 ] = 1 f[u][0]=1 f[u][0]=1只能当前u这个结点是危险结点时,满足
f [ u ] [ 1 ] ∗ = ( f [ v ] [ 0 ] + f [ v ] [ 1 ] ) f[u][1] * =(f[v][0]+f[v][1]) f[u][1]=(f[v][0]+f[v][1])当前结点可能是危险结点,也可能不是,
如果是危险结点那么上一个结点就不是危险结点,如果当前结点不是危险结点,那么上一个一定是危险结点
f [ u ] [ 2 ] = ( f [ u ] [ 2 ] + f [ u ] [ 1 ] ) f[u][2]=(f[u][2]+f[u][1]) f[u][2]=(f[u][2]+f[u][1]):讨论同 f [ u ] [ 1 ] f[u][1] f[u][1]

#include <bits/stdc++.h>
#define int long long
#define rep(i,a,b) for(int i = (a); i <= (b); ++i)
#define fep(i,a,b) for(int i = (a); i >= (b); --i)
#define pii pair<int, int>
#define ll long long
#define db double
#define endl '\n'
#define x first
#define y second
#define pb push_back

using namespace std;
const int mod=998244353;
void solve() {
	int n;
	cin>>n;
	vector<vector<int>>g(n+1);
	rep(i,1,n-1){
		int u,v;
		cin>>u>>v;
		g[u].pb(v);
		g[v].pb(u);
	}
	vector<vector<int>>f(n+1,vector<int>(3));
	auto dfs=[&](auto &&dfs,int u,int fa)->void{
		f[u][0]=1;f[u][1]=1;
		for(auto v:g[u]){
			if(v==fa){
				continue;
			}
			dfs(dfs,v,u);
			f[u][1]*=(f[v][0]+f[v][1]);
			f[u][2]+=f[v][2]+f[v][1];
			rep(i,0,2){
				f[u][i]=(f[u][i]+mod)%mod;
			}
		}
	};
	dfs(dfs,1,-1);
	int ans=0;
	rep(i,0,2){
		ans=(ans+f[1][i])%mod;
	}
	cout<<(ans+mod)%mod<<endl;
}

signed main() {
	ios::sync_with_stdio(false);
	cin.tie(0);
	cout.tie(0);
//	freopen("1.in", "r", stdin);
	int _;
	cin>>_;
	while(_--)
	solve();
	return 0;
}
  • 21
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值