题目练习_跳骚_幸运数字_解方程

这篇博客探讨了在编程问题中如何运用数学和算法思维。第一部分介绍了跳骚问题,通过分析数字序列和步数,计算可能的卡片组合。第二部分讨论了幸运数字的概念,寻找连续8的倍数。最后一部分涉及解方程问题,特别是寻找满足特定立方关系的正整数。文章通过实例展示了数学在解决复杂编程挑战中的重要性。
摘要由CSDN通过智能技术生成

跳骚

题目大意

有一只跳骚,有一张卡片,卡片上有n+1个自然数,最后且最大的一个数是m,前面的n个数都比m小。跳骚可以向左向右跳,但是跳的步数只能是卡片上的数字。如果跳骚可以跳到它初始位置的左边一个位置,那就说这张卡片是成功的。给定n和m,问你有几张成功的卡片。

思路

我们设第i张卡片的值为Di,使用的次数为Xi(Xi的正负代表跳骚跳的方向),则Di和Xi应该满足以下关系

代码

#include <iostream>
#include <bits/stdc++.h>

#define inf 0x3f3f3f3f
#define mod 1000000007
#define lmax 1000
#define pi 3.141592653589793238462643383279
#define eps 1e-7

using namespace std;
typedef long long ll;
typedef __int128 inta;

void scan(__int128 &x)//输入
{
	x=0;int f=1;char ch=getchar();
	while (!isdigit(ch)){if (ch=='-')f=-1;ch=getchar();}
	while(isdigit(ch)){x=x*10+ch-48;ch=getchar();}
	x*=f;
}
inline void print(__int128 x)//输出
{
	if(x<0){
		putchar('-');
		x=-x;
	}
	if(x>9) print(x/10);
	putchar(x%10+'0');
}
typedef struct
{
    inta num,many;
}node;
node factor[10000];
inta total;
inta powe(inta x,inta y);
void generation_factors(inta x);

int main()
{
    inta n,m,sum;
    int t;
    scanf("%d",&t);
    while(t--)
    {
        scan(n);
        scan(m);
        sum=0;
        generation_factors(m);
        for(inta i=total;i>=0;i--)
        {
            if(factor[i].many%2)
                sum-=powe(m/factor[i].num,n);
            else
                sum+=powe(m/factor[i].num,n);
        }
        print(sum);
        printf("\n");
    }
    return 0;
}

inta powe(inta x,inta y)//计算x的y次方的值
{
    inta temp;
    temp=x;
    for(inta i=1;i<y;i++)
        temp*=x;
    return temp;
}

void generation_factors(inta x)//生成x的所有因子
{
    total=0;
    factor[0].num=1;
    factor[0].many=0;
    for(inta i=2;i*i<=x;i++)
    {
        if(x%i==0)
        {
            while(!(x%i))
                x/=i;
            for(inta j=0;j<=total;j++)
            {
                factor[total+1+j].num=i*factor[j].num;
                factor[total+1+j].many=factor[j].many+1;
            }
            total=total*2+1;
        }
    }
    if(x!=1)
    {
        for(inta i=0;i<=total;i++)
        {
            factor[total+i+1].num=x*factor[i].num;
            factor[total+i+1].many=factor[i].many+1;
        }
        total=total*2+1;
    }
}

幸运数字

题目大意

给定一个数字n,让你求出最少几个连续的8能整除n,如果没有则输出"0"。

思路

首先构造一个全8数字为[8/9*(10x-1)],其中x为全8数字的位数,那么原题就变成求最小的x,满足题目条件。
这里面我打错号的两个式子是错的,应该将9/8改为8/9.

代码

#include <iostream>
#include <bits/stdc++.h>

#define inf 0x3f3f3f3f
//#define mod 1000000007
#define lmax 1000
#define pi 3.141592653589793238462643383279
#define eps 1e-7

using namespace std;
typedef long long ll;
//typedef __int128 inta;

ll mod(ll a,ll b,ll c);
ll modd(ll a,ll b,ll c);
void generation_factors(ll x);
ll gcd(ll a,ll b);
ll phi(ll x);
ll c[10000];
ll many;

int main()
{
    ll n,l,m,minn;
    int tcase=0;
    while(~scanf("%lld",&n))
    {
        if(n==0)
            break;
        printf("Case %d:",++tcase);
        l=9*n/gcd(n,8);
        minn=l+1;
        if(!(l%2)||!(l%5))//这里一开始一直没看懂,应该是和公式中的10有关,2和5都是10的因数
        {
            printf("0无解\n");
            continue;
        }
        m=phi(l);
        generation_factors(m);
        for(int i=1;i<=many;i++)
        {
            if(c[i]<minn&&modd(10,c[i],l)==1)
                minn=c[i];
        }
        printf("%lld\n",minn);
    }
    return 0;
}


ll mod(ll a,ll b,ll c)//特殊处理的a*b mod c求值运算
{
    ll t1,t2,t3,t4,k=1000000,temp;
    t1=a/k;
    t2=a%k;
    t3=b/k;
    t4=b%k;
    temp=(((k*k)%c)*((t1*t3)%c)+(t2*t3)%c*k%c+(t1*t4)%c*k%c+(t2*t4)%c)%c;
    return temp;
}
ll gcd(ll a,ll b)//辗转相除求最大公因数
{
    if(a<b)swap(a,b);
    if(b==0)
        return a;
    return gcd(b,a%b);
}
ll phi(ll x)//求x的欧拉函数值
{
    ll temp=x;
    for(int i=2;i*i<=x;i++)
    {
        if(x%i==0)
        {
            while(x%i==0)
                x/=i;
            temp=temp/i*(i-1);
        }
    }
    if(x!=1)
        temp=temp/x*(x-1);
    return temp;
}
void generation_factors(ll x)//生成x的所有因子,结果保存在c数组里
{
    ll ss,sk;
    c[1]=1;
    many=1;
    for(ll i=2;i*i<=x;i++)
    {
        if(!(x%i))
        {
            ss=1;
            while(!(x%i))
            {
                sk=many;
                for(ll j=ss;j<=sk;j++)
                {
                    c[++many]=c[j]*i;
                }
                x/=i;
                ss=sk+1;
            }
        }
    }
    sk=many;
    if(x!=1)
        for(ll i=1;i<=sk;i++)
            c[++many]=c[i]*x;
}
ll modd(ll a,ll b,ll c)//快速计算a的b次方模c的值
{
    ll ans,temp;
    ans=1;
    temp=a%c;
    while(b!=0)
    {
        if(b%2)
            ans=mod(ans,temp,c);
        temp=mod(temp,temp,c);
        b/=2;
    }
    return ans;
}

解方程

题目大意

给一个质数P,问是否存在正整数N,M使得N3+P*N2=M3
如果存在,输出yes,否则输出no。

思路

代码

里面有二分查找的函数代码。

#include <iostream>
#include <bits/stdc++.h>

#define inf 0x3f3f3f3f
#define mod 1000000007
#define lmax 1000
#define pi 3.141592653589793238462643383279
#define eps 1e-7

using namespace std;
typedef long long ll;
ll binary__search(ll p);

int main()
{
    ll p;
    int t;
    scanf("%d",&t);
    while(t--)
    {
        scanf("%lld",&p);
        if(binary__search(p))
            printf("YES\n");
        else
            printf("NO\n");
    }
    return 0;
}

ll binary__search(ll p)
{
    ll minn=1,maxx=20000000000,mid,temp;
    mid=(maxx+minn)/2;
    while(minn<=maxx)
    {
        temp=3*mid*mid+3*mid+1;
        if(temp==p)
            return mid;
        if(temp<p)
            minn=mid+1;
        else
            maxx=mid-1;
        mid=(minn+maxx)/2;
    }
    return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值