Round #518 (Div. 2) (题解)

A

题解:简单题直接(l+k)/m判断是否小于n

#include<bits/stdc++.h>
using namespace std;
#define clr(a) memset(a,b,sizeof(a))
#define reg    register
#define il     inline
typedef long long ll;
const int maxn=1000+9;
ll n,m,k,l;
int main()
{
    cin.tie(0);//取消cin的同步
    cout.tie(0);//取消cout的同步
    #ifndef  ONLY_JUDGE
    //freopen("data.txt","r",stdin);
    #endif
    cin>>n>>m>>k>>l;
    ll un=ceil((l+k)*1.0/m);
    if(un*m>n){puts("-1");return 0;}
    printf("%lld\n",un);
    return 0;
}

B

题解:就是计算b的因数个数

#include<bits/stdc++.h>
using namespace std;
#define clr(a) memset(a,b,sizeof(a))
#define reg    register
#define il     inline
typedef long long ll;
const int maxn=1000+9;
const ll tmaxn=1e18;
void solve(ll tes)
{
    ll ans=0;
    for(reg int i=1;i<=sqrt(tes);++i)
    {
        if(tes%i==0){ans+=2;}
        if(tes%i==0&&tes/i==i){ans--;}
    }
    cout<<ans<<endl;
    return ;
}

int main()
{
    cin.tie(0);//取消cin的同步
    cout.tie(0);//取消cout的同步
    #ifndef  ONLY_JUDGE
    //freopen("data.txt","r",stdin);
    #endif
    ll tes;
    cin>>tes;
    solve(tes);
    return 0;
}

C

题解:模拟设一个数cunt表示有关系的颜色cunt从n+1开始计算当有关联的时候cunt++存入到对应的横坐标如果是单独的就存放本身

#include<bits/stdc++.h>
using namespace std;
#define clr(a) memset(a,b,sizeof(a))
#define reg    register
#define il     inline
typedef long long ll;
const int maxn=1000+9;
int main()
{
    cin.tie(0);//取消cin的同步
    cout.tie(0);//取消cout的同步
    #ifndef  ONLY_JUDGE
    //freopen("data.txt","r",stdin);
    #endif
    int m,n;
    cin>>n>>m;
    vector<int>  ve[105];
    int a,b,cur=n+1;
    for(reg int i=0;i<m;i++)
    {
        cin>>a>>b;
        if(a==b){continue;}
        ve[a].push_back(cur);
        ve[b].push_back(cur);
        cur++;
    }
    for(reg int i=1;i<=n;i++)
    {
        if(ve[i].size()==0){ve[i].push_back(i);}
        cout<<ve[i].size()<<endl;
        for(reg auto t:ve[i]){printf("%d %d\n",i,t);}
    }
    return 0;
}

D

一道简单的dp,定义三维数组dp[2][j][0/1/2] 对于每一个数他的可能可由前的的数转化过来j表示在200里面数 当当前数为j时可以与前一个数组成多少种类型0表示ai=ai-1   1表示ai<ai-1  2表示ai=ai-1;一次类推然后取最后一个位置的符合条件的的数

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#include<queue>
#include<set>
#include<vector>
#include<map>
using namespace std;
#define clr(a,b) memset(a,b,sizeof(a))
#define reg    register
#define il     inline
typedef long long ll;
const int maxn = 100010;
const int minn = 200;
const int mod = 998244353;
int n, a[maxn];
ll dp[3][minn][4];
il ll solve()
{
	clr(dp, 0);
	for (reg int i = 1; i <= 200; ++i)
	{
		if (a[1] == -1 || a[1] == i) dp[1][i][2] = 1;
		else                         dp[1][i][2] = 0;
	}
	ll tm = 0;
	for (reg int i = 2; i <= n; ++i)
	{
		for (reg int j = 1; j <= 200; ++j)//ai=ai-1
		{
			if (a[i] == -1 || a[i] == j)
				dp[i%2][j][0] = (dp[(i - 1)%2][j][0] + dp[(i - 1)%2][j][1] + dp[(i - 1)%2][j][2]) % mod;
			else
				dp[i%2][j][0] = 0;
		}
		tm = 0;
		for (reg int j = 200; j > 0; --j)//ai<ai-1
		{
			if (a[i] == -1 || a[i] == j) { dp[i%2][j][1] = tm; }
			else dp[i%2][j][1] = 0;
			tm = (tm + dp[(i - 1)%2][j][0] + dp[(i - 1)%2][j][1]) % mod;
		}
		tm = 0;
		for (reg int j = 1; j <= 200; ++j)//ai>ai-1
		{
			if (a[i] == -1 || a[i] == j) { dp[i%2][j][2] = tm; }
			else  dp[i%2][j][2] = 0;
			tm = (tm + dp[(i - 1)%2][j][0] + dp[(i - 1)%2][j][1] + dp[(i - 1)%2][j][2]) % mod;
		}

	}
	ll ans = 0;
	for (reg int i = 1; i <= 200; i++)
	{
		ans = (ans + dp[n%2][i][0] + dp[n%2][i][1]) % mod;
	}
	return ans;
}
int main()
{
	cin.tie(0);//取消cin的同步
	cout.tie(0);//取消cout的同步
	cin >> n;
    clr(a, 0);
    for (reg int i = 1; i <= n; ++i)
    {
        cin >> a[i];
    }
    cout << solve() << endl;
	return 0;
}


E

题解:K这个树满足表示一共有k+1层 从根节点开始下的k层每一个的父节点下面必须要有三个孩子节点,直接先求出这棵树的根节点然后bfs判断 求根节点可以去孩子节点为1的叶子节点往上递归当递归的层数为2*k层时就退出 用栈存储每一层的节点取出第k的位置的节点就是根节点 然后bfs判断

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#include<queue>
#include<set>
#include<stack>
#include<vector>
#include<map>
using namespace std;
#define clr(a,b) memset(a,b,sizeof(a))
#define reg    register
#define il     inline
typedef long long ll;
const int maxn = 100010;
const int minn = 200;
const int mod = 998244353;
vector<int> ve[maxn];
int n, k;
int vis[maxn] = { 0 };
stack<int> sta;
int  getRoot(int deep, int x, int pre)
{
	if (deep == 2*k) { return 1; }
	for (auto i : ve[x])
	{
		if (i == pre) { continue; }
		sta.push(i);
		if (getRoot(deep + 1, i, x)) { return 1; }
		sta.pop();
	}
	return 0;
}
int bfs(int root)
{
	if (ve[root].size() < 3) { return 0; }
	queue<int> qu;
	qu.push(root);
	vis[root] = k+1;
	while(!qu.empty())
	{
		int u=qu.front();qu.pop();
		for(auto i:ve[u])
		{
			if(vis[i]){continue;}
			vis[i] = vis[u] - 1;
			if (vis[i] > 1 && ve[i].size() < 4) { return 0; }
			if (vis[i] == 1 && ve[i].size() > 1) { return 0; }
			qu.push(i);
		}
	}
	return 1;
}
int main()
{
	cin.tie(0);
	cout.tie(0);
	cin >> n >> k;
	int a, b, tm = 0;
	for (reg int i = 0; i < n - 1; i++)
	{
		cin >> a >> b;
		ve[a].push_back(b);
		ve[b].push_back(a);
		tm = ve[a].size() == 1 ? a : tm;
		tm = ve[b].size() == 1 ? b : tm;
	}
	int flag = 1;
	if (getRoot(0, tm, 0) == 0)
	{
		flag = 0;
	}
	else
	{
		int root = 0;
		while (!sta.empty())
		{
			root++;
			if (root == k+1) { root = sta.top(); break; }
			sta.pop();
		}
		flag=bfs(root);
	}
	puts(flag ? "Yes" : "No");
	return 0;
}


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值