Codeforces Round 992 (Div. 2)

这场cf只在b卡了一下,因为b真是犯蠢了,我以为会向下取整,结果是完全就不取整,或者说是向上取整,卡了我半个小时,要不是紧急看了题一下,昨天那场就毁了

话不多说,直接开讲

A. Game of Division

思路:很容易就能看出来就是同余定理,能够找到一个取模k的数,且只有这一个数取模k为当前的余数,那么就输出这个数,否则一定存在两个数相减会导致能被k整除

#include <bits/stdc++.h>  
using namespace std;  
#define int long long  

int t;  
int n, k;  
int a[200005];  

void solve() {  
    cin >> n >> k;  
    int m[k + 1];  
    memset(m, 0, sizeof(m));  
    int index[k + 1]; 
    memset(index, -1, sizeof(index)); 

    for (int i = 1; i <= n; i++) {  
        cin >> a[i];  
        a[i] = a[i] % k;  
        m[a[i]]++;  
        index[a[i]] = i;  
    }  

    for (int i = 0; i < k; i++) {  
        if (m[i] == 1) {  
            cout << "YES\n";  
            cout << index[i] << "\n"; 
            return;  
        }  
    }  
    
    cout << "NO\n";  
}  

signed main() {  
    ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);  
    cin >> t;  
    while (t--) {  
        solve();  
    }  
    return 0;  
}

 B. Paint a Strip

思路:我们发现,如果要输出最小的第一次操作,那么我们的放置位置一定是

1,4,10,22防置,为什么呢?

因为我们手玩一下,就可简单的发现,其实在1,4放完之后,可以直接2操作将前四个都变成1,然后在10再放置一个,就会有5个1,刚好能够把1~10全部渲染,后面同理可得

找到规律,flag=2*flag+2;

#include<bits/stdc++.h>
using namespace std;
#define int long long
int t;
int n,k;
int a[200005];

void solve()
{
	cin>>n;
	if(n<=4)
	{
		if(n==1)
		{
			cout<<1<<"\n";
		}
		else
		{
			cout<<2<<"\n";
		}
	}
	else
	{
		int ans=2;
		int flag=4;
		while(flag<n)
		{
			flag=flag*2+2;
			ans++;
		}
		cout<<ans<<"\n";
	}
}

signed main()
{
    ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
	cin>>t;
	while(t--)
	solve();
	return 0;
}

 C. Ordered Permutations

思路:我自己纯手写了个数从2到4的情况下,有多少个是最大的,然后发现,当个数为n的时候,有2^(n-1)个数是最大的,如果k大于这个数,就是无解,否则有解

然后我自己又手玩了一下,又发现一个规律,我们每次一个分段的最小值都应当放在两边,当我们这个分段k值大于一半,那么我们当前位的数就放在末尾,否则放在第一位

然后我们就可以用类二进制思想轻松解决

#include<bits/stdc++.h>
using namespace std;
#define int long long
int t;
int n,k;
int l,r;
int a[200005];
int flag[200005];
int vec[200005];
void solve()
{
    cin>>n>>k;
    k--;
    memset(flag,-1,sizeof(flag));
    for(int i=n-1; i>=1; i--)
    {
        if(k&1)
        {
        	flag[i]=1;
		}
        k=k>>1;
    }
    if(k!=0)
    {
        cout<<-1<<"\n";
        return;
    }
    l=1,r=n;
    for(int i=1; i<=n; i++)
    {
        if(flag[i]==1)
		{
			vec[r--]=i;
		}
        else
        {
        	vec[l++]=i;
		}
    }
    for(int i=1; i<=n; i++)
	{
		cout<<vec[i]<<" ";
	}
	cout<<"\n";
}

signed main()
{
    ios::sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);
    cin>>t;
    while(t--)
        solve();
    return 0;
}

 D. Non Prime Tree

思路:我们将跟结点赋值为1,然后将后续其第一个子节点赋值为父节点的值+1,其余子节点与父节点的值的差值为除了2以外的偶数即可

#include<bits/stdc++.h>
using namespace std;
#define int long long
int t;
int n,k;
int u,v;
vector<int> e[200005];
int ans[200005];
int flag;
void dfs(int v,int fa)
{
	for(int u:e[v])
	{
		if(u!=fa)
		{
			ans[u]=flag+1;
			while(ans[u]!=ans[v]+1&&(ans[u]%2!=ans[v]%2||abs(ans[u]-ans[v])==2))
			{
				ans[u]++;
			}
			flag=ans[u];
			dfs(u,v);
		}
	}
	return ;
}
void solve()
{
	cin>>n;
	for(int i=1;i<=n-1;i++)
	{
		cin>>u>>v;
		e[u].push_back(v);
		e[v].push_back(u);
	}
	flag=1;
	ans[1]=1;
	dfs(1,-1);
	for(int i=1;i<=n;i++)
	{
		cout<<ans[i]<<" ";
		ans[i]=0;
		e[i].clear();
	}
	cout<<"\n";
}
signed main()
{
    ios::sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);
	cin>>t;
	while(t--)
	solve();
	return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值