codeforces1249

本文解析了三道算法竞赛题目,包括数分组优化、循环路径计算与GoodNumber求解,提供了清晰的思路与代码实现,是算法学习者的宝贵资源。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

A

题意:给你n个数,可以把他们分组,相差只为1的数不能分为一组,问能分几组

思路:最多能分两组,只要存在两个数相差为一就要分两组否则就是一组

#include <iostream>
#include <algorithm>
using namespace std;
const int MAXN = 105;
int arr[MAXN];
int main()
{
    int T;
    cin>> T;
    while(T--)
    {
        int n;
        cin >> n;
        for(int i=0;i<n;i++) cin >> arr[i];
        sort(arr,arr+n);
        int num=0,ans=1;
        for(int i=0;i<n-1;i++)
        {
            if(arr[i+1]-arr[i]==1)
                ans=2;
        }
        cout<<ans<<endl;
    }
    return 0;
}

B1

题意:从1到n,第i个数ai表示他结束后传给第ai个数,问你每个i多长时间能再传回自己

思路:每个i都有自己的循环,找到每个i在哪个循环里就行了,用栈保存每一个循环,找出他的大小。

#include <algorithm>
#include <iostream>
#include <cstring>
#include <stack>
using namespace std;
const int maxn = 2e5+100;
int vis[maxn];
int ans[maxn];
int   a[maxn];
stack<int>s;
int main()
{
    int t,n,x,day;
	int i,j;
    cin >> t;
    while(t--)
    {     
        cin >> n;
		memset(a,0,sizeof(a));
        memset(vis,-1,sizeof(vis));
        memset(ans,0,sizeof(ans));
        for(i=1;i<=n;i++)
            cin >> a[i]; 
        for(i=1;i<=n;i++)
        {
            day=0;
            if(vis[i]!=-1) continue;
            x=a[i];
            while(x!=i)
            {
                s.push(x);
                x = a[x];
            }
            s.push(x);
            day = s.size();
            while(!s.empty())
            {
 
                x=s.top();
				s.pop();
                ans[x] = day;
                vis[x] = 1;
            }
        }
 
        for(int i=1;i<=n;i++)
            cout <<ans[i]<<" ";
        cout <<endl;
    }
}

C:

题意:给你一个数,让你求大于等于他的最小good number

goodnumber 就是 由不同的3的次方加起来得到的数

思路:把他先转化为3进制的数,用一个数组保存,因为每个3的n次方只能加一次,所以某个位上如果是2那就是不行的,解决方法就是找到最大位上的2,然后从他再开始找0,把他之后的第一个0变成1。

#include <cstdio>
#include <cmath>
#include <iostream>
#include <algorithm>
#include <cstring>
#define ll long long
using namespace std;
ll bit[100];
ll quickpow(ll n, ll m){
    ll ans = 1;
    while(m){
        if(m&1) ans *= n;
        n*=n;
        m>>=1;
    }
    return ans;
}
int main(){
    int q;
    scanf("%d",&q);
    while(q--){
        ll n, nn, sum=0;
        memset(bit, 0, sizeof(bit));
        scanf("%I64d",&n);
        nn=n;
        ll tot=0;
        while(n) bit[++tot]=n%3, n/=3;
        ll i;
        for(i=tot; i>=1; i--)
            if(bit[i]==2) break;
        if(!i) printf("%I64d\n", nn);
        else{
            for(i++;;i++)
                if(bit[i]==0 || i>tot) {
                    bit[i]=1;
                    break;
                }
            if(i>tot) sum=quickpow(3, i-1);
            for(;i<=tot;i++) if(bit[i]==1) sum+=quickpow(3, i-1);
            printf("%I64d\n",sum);
        }
    }
    return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值