2024春算法训练4——函数与递归题解

news2025/1/31 2:49:00

一、前言

        感觉这次的题目都很好,但是E题....(我太菜了想不到),别人的题解都上百行了,晕;

二、题解

 A-[NOIP2010]数字统计_2024春算法训练4——函数与递归 (nowcoder.com)

这种题目有两种做法:1、计数dp,2、暴力(时间复杂度为0(n))

1、先讲暴力:直接枚举就行了,注意循环内要用一个变量代替i求i的数位上出现过的数字。

#include<iostream>
using namespace std;
int target=2;
int main(){
    int l,r;
    cin>>l>>r;
    int ans=0;
    for(int i=l;i<=r;i++){
        int s=i;
        while(s){
            int yu=s%10;
            if(yu==target){
                ans++;
            }
            s/=10;
        }
    }
    cout<<ans;
}

2、记数类dp

这里主要是分情况讨论,假设我们要求一个数字在从一到R中出现的次数,那么就等于求这个数字在每个数出现的次数。问题就转换成了求这个数字在这个数出现的次数,进一步转换成求这个数在要求的数的每一位出现的次数之和。假设我们一直一个数abcdef,要求数字1在第三位出现的次数:

(1)前三位是0~abc-1时,数字是xxx100~xxx199,所以有abc*100种取法

(2)前三位是abc(此时讨论d)

          (2.1)d<1 数字是abc000~abc099  此时有0种取法

          (2.2)d=1  数字是abc100~abc1ef 此时有ef+1种取法

          (2.3) d>1  数字可以取到abc100~abc199(实际范围是abc000~abcdef)  此时有100取法

如果是求区间l到r的个数的话就是用r的减去l的就可以了。特判0,但是这道题都是正整数,所以不用。

#include<algorithm>
#include<iostream>
#include<cstring>
#include<vector>
#include<cmath> 
#include<map>
#define pre(i,l,r)for(int i=l;i<=r;i++)
#define pr(i,r,l)for(int i=r;i>=l;i--)
using namespace std;
typedef long long ll;
typedef pair<int ,int>pii;

const int N=300010;

ll gcd(ll x,ll y)
{
	return !y?x:gcd(y,x%y);
} 

/*struct node
{
    char ch;
    int num;
    bool operator < (const struct node &A)
    {
        return num<A.num;
    }
}a[N];*/

int query(int x)
{
    int ret=0;
    while(x)
    {
        x/=10;
        ret++;
    }
    return ret;
}

int cnt(int t,int n) 
{
    int ret=0;int wei=query(n);
    pre(i,1,wei)
    {
        int p=pow(10,i-1);
        int l=n/p/10,r=n%p,d=n/p%10;
        
        /*t如果不为0,则按照一般的规则计算*/
        if(t)ret+=l*p;
        /*t如果为0,如果l为0,左边就是000..0前导0无效就不算,如果l不为0,因为t为0,所以不存在
00000...0....的情况,要从0000010...的情况开始*/
        if(!t&&l)ret+=(l-1)*p;
         /*(t||l)表示如果t为0,那么t就不能出现在最高位*/   
        if(d==t&&(t||l))ret+=r+1; 
        if(d>t&&(t||l))ret+=p;
    }
    return ret;
}

void solve()
{	
    int l,r;
    cin>>l>>r;
    
    cout<<cnt(2,r)-cnt(2,l-1);
} 

int main()
{
    int _;
    //cin>>_;
    _=1;
    while(_--)
    {
        solve();
    }
	
    return 0;
}

B-素数回文_2024春算法训练4——函数与递归 (nowcoder.com)

按照题目意思求出回文数,然后写一个判断质数的函数就可以了,注意一下数据范围要开ll

#include<algorithm>
#include<iostream>
#include<cstring>
#include<vector>
#include<cmath> 
#include<map>
#define pre(i,l,r)for(int i=l;i<=r;i++)
#define pr(i,r,l)for(int i=r;i>=l;i--)
using namespace std;
typedef long long ll;
typedef pair<int ,int>pii;

const int N=300010;

ll gcd(ll x,ll y)
{
	return !y?x:gcd(y,x%y);
} 

/*struct node
{
    char ch;
    int num;
    bool operator < (const struct node &A)
    {
        return num<A.num;
    }
}a[N];*/

bool isprime(ll a)
{
    if(a==1||a==0)return false;
    for(int i=2;i<=a/i;i++)if(a%i==0)return false;
    return true;
}

bool check(string a)
{
    ll ret=0;
    pre(i,0,a.size()-1)ret=ret*10+(a[i]-'0');
    
    if(isprime(ret))return true;
    return false;
}

void solve()
{	
    string a;
    cin>>a;
    
    pr(i,a.size()-2,0)a+=a[i];
    
    if(check(a))cout<<"prime";
    else cout<<"noprime";
} 

int main()
{
    int _;
    //cin>>_;
    _=1;
    while(_--)
    {
        solve();
    }
	
    return 0;
}

C-[NOIP1999]回文数_2024春算法训练4——函数与递归 (nowcoder.com)

用一个数组求回文数,与原数组相加,最后判断是否为回文数,重复以上步骤最多30次,

#include<algorithm>
#include<iostream>
#include<cstring>
#include<vector>
#include<cmath> 
#include<map>
#define pre(i,l,r)for(int i=l;i<=r;i++)
#define pr(i,r,l)for(int i=r;i>=l;i--)
using namespace std;
typedef long long ll;
typedef pair<int ,int>pii;

const int N=300010;

ll gcd(ll x,ll y)
{
	return !y?x:gcd(y,x%y);
} 

/*struct node
{
    char ch;
    int num;
    bool operator < (const struct node &A)
    {
        return num<A.num;
    }
}a[N];*/

int n;

//将字符转换成数字
int tr(char ch)
{
   return ch<='9'?(ch-'0'):(ch+10-'A');
}

//将数字转换成字符
char rt(int tt)
{
   return tt<=9?(tt+'0'):(tt-10+'A');
}

//判断当前的数是否回文
bool check(vector<char>x)
{
    int l=0,r=x.size()-1;
    while(l<r)
    {
        if(x[l]!=x[r])return false;
        l++;
        r--;
    }
    return true;
}

void solve()
{	
    cin>>n;
	string ss;
    cin>>ss;
    
    vector<char>a;
    pre(i,0,ss.size()-1)a.push_back(ss[i]);//a存储数
    
    int cnt=30;
    bool flag=1;
    if(check(a))
    {
        cout<<"STEP=0";
        return ;
    }
    while(cnt)
    {
        cnt--;
        int t=0;
        vector<char>temp,ans;//temp存储a的翻转数,ans临时存储计算结果
        pr(i,a.size()-1,0)temp.push_back(a[i]);

        //模拟不同进制的加法
        pr(i,a.size()-1,0)
        {
            int x=tr(a[i]),y=tr(temp[i]);
            int tt=(t+x+y)%n;
            t=(x+y+t)/n;
            char s=rt(tt);
            ans.push_back(s);
        }
        if(t)ans.push_back(rt(t));

        /*reverse(ans.begin(),ans.end());*/ //ans如果是回文数不会对结果有影响,但是如果不是也没有影响,这一步是多余的
        /*pre(i,0,ans.size()-1)cout<<ans[i];
        cout<<endl;*/

        if(check(ans))
        {
            cout<<"STEP="<<30-cnt;
            flag=0;
            break;
        }else a=ans;
    }
   if(flag) cout<<"Impossible!";
} 

int main()
{
    int _;
    //cin>>_;
    _=1;
    while(_--)
    {
        solve();
    }
	
    return 0;
}

D-素数中的等差数列_2024春算法训练4——函数与递归 (nowcoder.com)

先求质数,然后用一个数组将质数存储起来,(此时是有序的不用排序),然后从小到大枚举等差数列,每组等差数列最少有三个,还有可能多于三个,可以先保留最后两个然后枚举前面的。

#include<iostream>
#include<algorithm>
using namespace std;
int f[100010];
int  prime(int ans){
    if(ans==1)return 0;
    if(ans==2)return 1;
    for(int i=2;i<=ans/i;i++){
        if(ans%i==0)return 0;
    }
    return 1;
}
int main(){
    int k=0,p=0;
    int l,r;
    scanf("%d%d",&l,&r);
    for(int i=l;i<=r;i++){
    if(prime(i))f[k++]=i;
    }
    
    for(int i=0;i<k-3;i++){
        if(f[i+2]-f[i+1]==f[i+1]-f[i]){
        while(f[i+2]-f[i+1]==f[i+1]-f[i]){
              printf("%d ",f[i]);
            i++;
          }
            i--;
            printf("%d %d\n",f[i+1],f[i+2]);
            i+=2;
        }
    }
    return 0;
}

F-日历中的数字_2024春算法训练4——函数与递归 (nowcoder.com)

每个月的话年份和月份都不会变,这两者可以直接处理,但是日的话就要一个一个的枚举。

注意小于10的月份和日是要补0的;

#include<algorithm>
#include<iostream>
#include<cstring>
#include<vector>
#include<cmath> 
#include<map>
#define pre(i,l,r)for(int i=l;i<=r;i++)
using namespace std;
typedef long long ll;
typedef pair<int ,int>pii;

const int N=300010;

ll gcd(ll x,ll y)
{
	return !y?x:gcd(y,x%y);
} 

/*struct node
{
    char ch;
    int num;
    bool operator < (const struct node &A)
    {
        return num<A.num;
    }
}a[N];*/

int n;

int m1[]={0,31,28,31,30,31,30,31,31,30,31,30,31};
int m2[]={0,31,29,31,30,31,30,31,31,30,31,30,31};
map<int ,int>q;

bool check(int a)
{
    return((a%400==0)||(a%4==0&&a%100!=0))?true:false;
}

void solve1(int a,int b)
{
    if(a<10)q[0]+=b;
    while(a)
    {
        q[a%10]+=b;
        a/=10;
    }
}

void solve2(int x)
{
    pre(i,1,x)
    {
        if(i<10)q[0]++;
        int a=i;
        while(a)
        {
            q[a%10]++;
            a/=10;
        }
    }
}

void solve()
{	
    int year,month,target;
    while(cin>>year>>month>>target)
    {
        if(check(year))
        {
            solve1(year,m2[month]);
            solve1(month,m2[month]);
            solve2(m2[month]);
        }else
        {
            solve1(year,m1[month]);
            solve1(month,m1[month]);
            solve2(m1[month]);
        }
        cout<<q[target]<<endl;
        q.clear();
    }
} 

int main()
{
    int _;
    //cin>>_;
    _=1;
    while(_--)
    {
        solve();
    }
    return 0;
}

G-兔子的序列_2024春算法训练4——函数与递归 (nowcoder.com)

sqrt返回的是浮点数,因此如果要用其判断完全平方数就要将其转化为整形

#include<algorithm>
#include<iostream>
#include<cstring>
#include<vector>
#include<cmath> 
#include<map>
#define pre(i,l,r)for(int i=l;i<=r;i++)
#define pr(i,r,l)for(int i=r;i>=l;i--)
using namespace std;
typedef long long ll;
typedef pair<int ,int>pii;

const int N=300010;

ll gcd(ll x,ll y)
{
	return !y?x:gcd(y,x%y);
}

bool cmp(int a,int b)
{
    return a<b;
}

/*struct node
{
    char ch;
    int num;
    bool operator < (const struct node &A)
    {
        return num<A.num;
    }
}a[N];*/

int a[1010];
void solve()
{	
    int n;
    cin>>n;
    
    pre(i,1,n)cin>>a[i];
    sort(a+1,a+1+n,cmp);
    pr(i,n,1)if((int)sqrt(a[i])*(int)sqrt(a[i])!=a[i]){cout<<a[i];break;}
} 

int main()
{
    int _;
    //cin>>_;
    _=1;
    while(_--)
    {
        solve();
    }
	
    return 0;
}

H-小X的多边形_2024春算法训练4——函数与递归 (nowcoder.com)

这题是一道数学题,就是将多边形分割成三角形,然后将三角形面积计算转换成向量叉乘,刚好转换成一个点和其相邻点的向量叉乘,详细证明可以看下这个大牛的博客:

计算任意多边形的面积 - tenos - 博客园 (cnblogs.com)icon-default.png?t=N7T8https://www.cnblogs.com/TenosDoIt/p/4047211.html代码如下:

include<iostream>
#include<vector>
#include<cmath>
using namespace std;
int main()
{
    int n;
    cin>>n;
    vector<int>a,b;
    while(n--)
    {
    int x,y;
    cin>>x>>y;
    a.push_back(x);
    b.push_back(y);
    }
    int s=0;
    for(int i=0,j=1;i<a.size();i++,j++)
    {
        if(j==a.size())j=0;
        s+=a[i]*b[j];
        s-=a[j]*b[i];
    }
    int ans;
    if(s%2==0)ans=abs(s/2);
    else ans=abs(s/2)+1;
    cout<<ans;
    return 0;
}

I-The Biggest Water Problem_2024春算法训练4——函数与递归 (nowcoder.com)

对于任意一个十进制数x,x=a*10^n+b*10^(n-1)+......+c*10^0;如果每次只取其位数上的数,可以发现数会越变越小,所以一定有解。按照题意模拟即可

#include<iostream>
using namespace std;
int sum=0;
void solve(int n){
    int s=n;
    sum=0;
    while(s){
        sum+=s%10;
        s/=10;
    }
}
int main(){
    string c;
    cin>>c;
    for(unsigned int i=0;i<c.size();i++){
        sum+=c[i]-'0';
    }
    while(sum>=10){
     solve(sum);
    }
    cout<<sum;
}

J-小q的数列_2024春算法训练4——函数与递归 (nowcoder.com)

求值的话直接递归就行,但是求第一次出现的数的话要观察规律,发现是2的n次方减一

K-大吉大利,今晚吃鸡_2024春算法训练4——函数与递归 (nowcoder.com)、

此题有限制只能移动到相邻的柱子上面去我们可以将n个圆盘看成两部分,一部分是上面n-1个圆盘,另外一部分就是第n个圆盘,可以得出递归的步骤有如下几步:

如果n==1要跳两下

1、将(n-1)从A拿到C

2、将n从A拿到B;

3、将(n-1)从C拿到A

4、将n从B拿到C

5、将(n-1)从A拿到C;

当然事实上A,B,C不是固定的,固定的是A,B,C分别代表的起始柱,工具柱,目的柱,反正n被拿到目的柱后就可以忽略了,每次解决的都是n,当n-1递归到1时结束;记得特判0。

#include<algorithm>
#include<iostream>
#include<cstring>
#include<vector>
#include<cmath> 
#include<map>
#define pre(i,l,r)for(int i=l;i<=r;i++)
#define pr(i,r,l)for(int i=r;i>=l;i--)
using namespace std;
typedef long long ll;
typedef pair<int ,int>pii;

const int N=300010;

ll gcd(ll x,ll y)
{
	return !y?x:gcd(y,x%y);
} 

/*struct node
{
    char ch;
    int num;
    bool operator < (const struct node &A)
    {
        return num<A.num;
    }
}a[N];*/

ll ans=0;

void hanoi(int x)
{
    if(x==1){ans+=2;return ;}
    hanoi(x-1);
    ans++;
    hanoi(x-1);
    ans++;
    hanoi(x-1);
    
}

void solve()
{	
    int x;
    while(scanf("%d",&x)!=EOF){
        ans=0;
        if(x)hanoi(x);
        cout<<ans<<endl;
    }
} 

int main()
{
    int _;
    //cin>>_;
    _=1;
    while(_--)
    {
        solve();
    }
	
    return 0;
}

L-[NOIP2001]数的计算_2024春算法训练4——函数与递归 (nowcoder.com)

这题的题目描述有点问题建议去看原题。思路是如果一个数可以得到一个数那么他就可以得到这一个数的所有集合。P1028 [NOIP2001 普及组] 数的计算 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)icon-default.png?t=N7T8https://www.luogu.com.cn/problem/P1028

代码如下:

#include<algorithm>
#include<iostream>
#include<cstring>
#include<vector>
#include<cmath> 
#include<map>
#define pre(i,l,r)for(int i=l;i<=r;i++)
#define pr(i,r,l)for(int i=r;i>=l;i--)
using namespace std;
typedef long long ll;
typedef pair<int ,int>pii;

const int N=300010;

ll gcd(ll x,ll y)
{
	return !y?x:gcd(y,x%y);
} 

/*struct node
{
    char ch;
    int num;
    bool operator < (const struct node &A)
    {
        return num<A.num;
    }
}a[N];*/


int dp[N];

void init()
{
    pre(i,1,1010)dp[i]=1;
    
    pre(i,1,1010)
        pre(j,1,i/2)
        dp[i]+=dp[j];
}

void solve()
{	
    init();
    
    int n;
    cin>>n;
    cout<<dp[n]<<endl;
} 

int main()
{
    int _;
    //cin>>_;
    _=1;
    while(_--)
    {
        solve();
    }
	
    return 0;
}

M-[CSP2019]格雷码(code)_2024春算法训练4——函数与递归 (nowcoder.com)

非常适合递归的一道题:又题可知每次在前面要么加1,要么加0,那么我们可以通过判断

n位数第k位数是由(n-1)位第几个数变来的,如果k在前一半,那么加一个0,否则加一个1

如果k在前一半那么它在加0之前的那个数的位置一定是在(n-1)位的第k个,因为前半段是顺序,

反之k是(n-1)位数的第(2^n-k+1)个,因为后半段是逆序。一直递归到0,1,结束即可

#include<algorithm>
#include<iostream>
#include<cstring>
#include<vector>
#include<cmath> 
#include<map>
#define pre(i,l,r)for(int i=l;i<=r;i++)
#define pr(i,r,l)for(int i=r;i>=l;i--)
using namespace std;
typedef long long ll;
typedef pair<int ,int>pii;

const int N=300010;

ll gcd(ll x,ll y)
{
	return !y?x:gcd(y,x%y);
} 

/*struct node
{
    char ch;
    int num;
    bool operator < (const struct node &A)
    {
        return num<A.num;
    }
}a[N];*/

string t[2]={"0","1"};

void finds(int x,ll k)
{
    if(x==1&&k==0){cout<<"0";return;}
    if(x==1&&k==1){cout<<"1";return;}
    
    if(k>=(ll)pow(2,x-1)){cout<<"1";k=(ll)pow(2,x)-k-1;finds(x-1,k);}
    else {cout<<"0";finds(x-1,k);}
}

void solve()
{	
    ll n,k;
    cin>>n>>k;
    
    finds(n,k);
} 

int main()
{
    int _;
    //cin>>_;
    _=1;
    while(_--)
    {
        solve();
    }
	
    return 0;
}

N-[NOIP2011]瑞士轮_2024春算法训练4——函数与递归 (nowcoder.com)

这题用sort就逃不了tle的命运,所以再看了大佬的题解后发现这题目的每一轮的排序时间复杂度可以用归并排序控制在O(n),从而逃脱tle的魔爪。

每一轮从前往后将所有人分为胜者组和败者组,因为胜者组和败者组是默认有序的,因为一开始就是按分数大小排序的,所以前一组的胜者的分数一定大于后一组的胜者的分数。然后这时候用归并排序其时间复杂度稳定是O(n)。

#include<algorithm>
#include<iostream>
#include<cstring>
#include<vector>
#include<cmath> 
#include<map>
#define pre(i,l,r)for(int i=l;i<=r;i++)
#define pr(i,r,l)for(int i=r;i>=l;i--)
using namespace std;
typedef long long ll;
typedef pair<int ,int>pii;

const int N=1000010;

ll gcd(ll x,ll y)
{
	return !y?x:gcd(y,x%y);
} 

struct node
{
    int score,ability,h;
    bool operator < (const struct node &A)
    {
        if(score!=A.score)return score>A.score;
        return h<A.h;
    }
}a[N],A[N],B[N];

int n,r,q,cnt=1;

void merge_sort()
{
    int i=1,j=1,k=1;
    while(i<=n/2&&j<=n/2)
    {
        if(A[i].score>B[j].score || (A[i].score == B[j].score && A[i].h<B[j].h))
        {
            a[k].score=A[i].score;
            a[k].h=A[i].h;
            a[k++].ability=A[i++].ability;
        }
        else{
             a[k].score=B[j].score;
            a[k].h=B[j].h;
            a[k++].ability=B[j++].ability;
        }
    }
    while(i<=n/2)
    {
        a[k].score=A[i].score;
        a[k].h=A[i].h;
        a[k++].ability=A[i++].ability;
    }
    while(j<=n/2)
    {
           a[k].score=B[j].score;
           a[k].h=B[j].h;
           a[k++].ability=B[j++].ability;
    }
}

void solve()
{	
    cin>>n>>r>>q;
    n*=2;
    
   pre(i,1,n)cin>>a[i].score,a[i].h=i;
   pre(i,1,n)cin>>a[i].ability;
    
   sort(a+1,a+1+n);
    
    for(int j=1;j<=r;j++)
    {
        cnt=1;
        for(int i=1;i<=n;i+=2)
        {
            if(a[i].ability>a[i+1].ability)
            {
                A[cnt].ability=a[i].ability;
                B[cnt].ability=a[i+1].ability;
                A[cnt].score=a[i].score+1;
                B[cnt].score=a[i+1].score;
                A[cnt].h=a[i].h;
                B[cnt++].h=a[i+1].h;
            }
            else
            {
                A[cnt].ability=a[i+1].ability;
                B[cnt].ability=a[i].ability;
                A[cnt].score=a[i+1].score+1;
                B[cnt].score=a[i].score;
                A[cnt].h=a[i+1].h;
                B[cnt++].h=a[i].h;
            }
            
        }
        merge_sort();
        
    }
    cout<<a[q].h<<endl;
} 

int main()
{
    int _;
    //cin>>_;
    _=1;
    while(_--)
    {
        solve();
    }
	
    return 0;
}

O-[NOIP2007]Hanoi双塔问题_2024春算法训练4——函数与递归 (nowcoder.com)

这题应该跟上面那题差不多,特点是没有条件限制,但是它的数据范围有点大。

思路参考上面,可以得出递归的步骤是:

n==1时走一步

1、将(n-1)从A拿到B

2、将(n)从A拿到C

3、将(n-1)从B拿到B

但是这题用递归会炸、、范围原因,只要改一改这其实是一道简单的dp题

递推公式如下:

考虑到结果会很大,于是我们可以采用高精度乘法:

(关于高精度可以看看这里:高精度运算-CSDN博客)

#include<algorithm>
#include<iostream>
#include<cstring>
#include<vector>
#include<cmath> 
#include<map>
#define pre(i,l,r)for(int i=l;i<=r;i++)
#define pr(i,r,l)for(int i=r;i>=l;i--)
using namespace std;
typedef long long ll;
typedef pair<int ,int>pii;

const int N=300010;

ll gcd(ll x,ll y)
{
	return !y?x:gcd(y,x%y);
} 

/*struct node
{
    char ch;
    int num;
    bool operator < (const struct node &A)
    {
        return num<A.num;
    }
}a[N];*/

int dp[201][201];

void init()
{
    dp[1][1]=1;
    pre(i,2,201)
    {
       pre(j,1,201)dp[i][j]=dp[i-1][j]*2;

       int t=0;
       dp[i][1]++;
       pre(j,1,201)if(dp[i][j]>=10)dp[i][j+1]+=dp[i][j]/10,dp[i][j]%=10;
       
    }
}

void solve()
{	
    init();
    
    int n;
    cin>>n;
    int flag=201;
    
    pre(j,1,201)dp[n][j]*=2;
    pre(j,1,201)if(dp[n][j]>=10)dp[n][j+1]+=dp[n][j]/10,dp[n][j]%=10;
    
    pr(i,201,1)if(dp[n][i]){flag=i;break;}
    pr(i,flag,1)cout<<dp[n][i];
} 

int main()
{
    int _;
    //cin>>_;
    _=1;
    while(_--)
    {
        solve();
    }
	
    return 0;
}

P-[NOIP1998]幂次方_2024春算法训练4——函数与递归 (nowcoder.com)

这里的子任务就是如何将一个数表示成2的幂次方的问题,对于任意一个数,如果它大于等于2^n,那么他就一定可以分解成2^n+..........的形式,那么我们的一个任务就是表示2^n,然后进一步表示n,n也一定可以表示成2^m+.....的形式。(n,m均为常数)。直到其中有一个环节能够用2或者1表示,那么递归结束。至于加号,从上面的表示来看,只要递归没结束,即x不为0,就有加号。

#include<algorithm>
#include<iostream>
#include<cstring>
#include<vector>
#include<cmath> 
#include<map>
#define pre(i,l,r)for(int i=l;i<=r;i++)
#define pr(i,r,l)for(int i=r;i>=l;i--)
using namespace std;
typedef long long ll;
typedef pair<int ,int>pii;

const int N=300010;

ll gcd(ll x,ll y)
{
	return !y?x:gcd(y,x%y);
} 

/*struct node
{
    char ch;
    int num;
    bool operator < (const struct node &A)
    {
        return num<A.num;
    }
}a[N];*/

void gui(int x)
{
   pr(i,14,0)
   {
        if(pow(2,i)<=x)
        {
            if(i==1)cout<<2;
            else if(i==0)cout<<"2(0)";
            else {cout<<"2(";gui(i);cout<<")";}
            
             x-=pow(2,i);
            if(x)cout<<"+";
        }
       
   }
    
}

void solve()
{	
    int n;
    cin>>n;
    gui(n);
} 

int main()
{
    int _;
    //cin>>_;
    _=1;
    while(_--)
    {
        solve();
    }
	
    return 0;
}

Q-[NOIP2001]一元三次方程求解_2024春算法训练4——函数与递归 (nowcoder.com)

这题有两个解法:1、暴力 2、二分,3、盛金公式。

1、暴力感觉有点勉强(能做出来就是win)直接枚举所有的可能解,注意要时间复杂度和eps的取值

#include<algorithm>
#include<iostream>
#include<cstring>
#include<vector>
#include<cmath> 
#include<map>
#define pre(i,l,r)for(int i=l;i<=r;i++)
#define pr(i,r,l)for(int i=r;i>=l;i--)
using namespace std;
typedef long long ll;
typedef pair<int ,int>pii;

const int N=300010;

ll gcd(ll x,ll y)
{
	return !y?x:gcd(y,x%y);
} 

/*struct node
{
    char ch;
    int num;
    bool operator < (const struct node &A)
    {
        return num<A.num;
    }
}a[N];*/

double a,b,c,d;

double f(double x){
	double ret=a*x*x*x+b*x*x+c*x+d;
	return ret;
}
double eps=1e-2;

void solve()
{	
    cin>>a>>b>>c>>d;
	int cnt=0;
	double i=-100.0;
	while(cnt<3&&i<=100){
		if(fabs(f(i))<eps){
		printf("%.2f ",i);
		cnt++;
		i+=1;
		}	
		i+=0.001;
  }
} 

int main()
{
    int _;
    //cin>>_;
    _=1;
    while(_--)
    {
        solve();
    }
	
    return 0;
}

 2、二分:题目说如果两端点值异号那么区间至少有一个解,而且两个解的距离大于等于1,所以我们对每个长度为一两端点异号的区间进行二分的话,不考虑两端点都是解的情况下,一定可以二分出一个正解。同时要特判端点值,因为区间为闭区间。

#include<algorithm>
#include<iostream>
#include<cstring>
#include<vector>
#include<cmath> 
#include<map>
#define pre(i,l,r)for(int i=l;i<=r;i++)
#define pr(i,r,l)for(int i=r;i>=l;i--)
using namespace std;
typedef long long ll;
typedef pair<int ,int>pii;

const int N=300010;

ll gcd(ll x,ll y)
{
	return !y?x:gcd(y,x%y);
} 

/*struct node
{
    char ch;
    int num;
    bool operator < (const struct node &A)
    {
        return num<A.num;
    }
}a[N];*/

double a,b,c,d;

double f(double x){
	return a*x*x*x+b*x*x+c*x+d;
}
double eps=1e-2;

void solve()
{	
    scanf("%lf %lf %lf %lf",&a,&b,&c,&d);
    int cnt=0;
	pre(i,-100,100)
    {
        double y1=f(i*1.0);
        double y2=f((i+1)*1.0);
        if(!y1)
        {   
            cnt++;
            printf("%.2lf ",i*1.0);
        }
        if(y1*y2<0)
        {
             double l=i,r=i+1;
            while(r-l>=0.001)
            {    
                double mid=(l+r)/2;
                if(f(mid)*f(l)<=0)r=mid;
                else l=mid;
             }
            printf("%.2lf ",l);
            cnt++;
        }
        if(cnt==3)break;
    }
} 

int main()
{
    int _;
    //cin>>_;
    _=1;
    while(_--)
    {
        solve();
    }
	
    return 0;
}

 3、盛金公式,建议自行搜索。

R-[NOIP2002]过河卒_2024春算法训练4——函数与递归 (nowcoder.com)

这题看起来好有感觉,直接用dp写了。我们可以先忽略马这个元素,如果只用求路径数的话,那么

对于所有第一排和第一列的格子,显然都只有一种走法,然后对于其他格子的路径总数等于其上面格子的路径总数加上左边的格子的路径总数。

加入马之后要考虑其影响,1、如果马可以出现在第一行或者第一列那么第一行或者第一列在那个点后面的格子就不可能到达了;2、如果上面或者左边马可以到达那么那个点的路径数一定为0,

代码如下:

#include<algorithm>
#include<iostream>
#include<cstring>
#include<vector>
#include<cmath> 
#include<map>
#define pre(i,l,r)for(int i=l;i<=r;i++)
#define pr(i,r,l)for(int i=r;i>=l;i--)
using namespace std;
typedef long long ll;
typedef pair<int ,int>pii;

const int N=300010;

ll gcd(ll x,ll y)
{
	return !y?x:gcd(y,x%y);
} 

/*struct node
{
    char ch;
    int num;
    bool operator < (const struct node &A)
    {
        return num<A.num;
    }
}a[N];*/
int dx[]={2,2,1,1,-2,-2,-1,-1},dy[]={1,-1,2,-2,1,-1,2,-2};
ll ans[21][21];

void solve()
{	
    int n,m,a,b;
    cin>>n>>m>>a>>b;
    
    ans[a][b]=-1;
    pre(i,0,7)
    {
        int x=a+dx[i],y=b+dy[i];
        if(x>=0&&x<=n&&y>=0&&y<=m)ans[x][y]=-1;
    }
    
    pre(i,0,n){if(ans[i][0]!=-1)ans[i][0]=1;else break;}
    pre(i,0,m){if(ans[0][i]!=-1)ans[0][i]=1;else break;}
    
    pre(i,1,n){
        pre(j,1,m)
        {
           if(ans[i][j]==-1)continue;
           if(ans[i-1][j]!=-1)ans[i][j]+=ans[i-1][j];
           if(ans[i][j-1]!=-1)ans[i][j]+=ans[i][j-1];
        }
    }
    cout<<ans[n][m];
} 

int main()
{
    int _;
    //cin>>_;
    _=1;
    while(_--)
    {
        solve();
    }
	
    return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1575644.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

蓝桥杯算法题:卡片换位

问题描述 你玩过华容道的游戏吗&#xff1f;这是个类似的&#xff0c;但更简单的游戏。 看下面 2 x 3 的格子 --------- | A | * | * | --------- | B | | * | --------- 1 2 3 4 5 在其中放 5 张牌&#xff0c;其中 A 代表关羽&#xff0c;B 代表张飞&#xff0c;* 代表士兵…

【正点原子探索者STM32F4】TFTLCD实验学习记录:FSMC控制 TFTLCD的寄存器配置

FSMC控制 TFTLCD的寄存器配置 异步模式 A控制 TFTLCDFSMC寄存器配置ILI9341电平持续时间要求 参考 异步模式 A控制 TFTLCD LCD以ILI9341为例 FSMC寄存器配置 对于异步突发访问方式&#xff0c; FSMC 主要设置 3 个时间参数&#xff1a;地址建立时间(ADDSET)、 数据 建立时间…

基于单片机风力发电机迎风面对风向的追踪系统设计

**单片机设计介绍&#xff0c;基于单片机风力发电机迎风面对风向的追踪系统设计 文章目录 一 概要二、功能设计三、 软件设计原理图 五、 程序六、 文章目录 一 概要 基于单片机风力发电机迎风面对风向的追踪系统设计是一个涉及单片机编程、传感器技术、机械控制等多个领域的综…

python 04字典映射

1.创建字典 &#xff08;1&#xff09;通过自己的输入创建字典 字典用大括号&#xff0c;至此&#xff0c;小括号( )表示元组&#xff0c;中括号[ ]表示列表&#xff0c;大括号{ }表示字典&#xff0c;python中最常用的三种数据结构就全了 &#xff08;2&#xff09;通过其他…

今日头条signature参数js逆向(爬虫)

今日头条是ajax动态加载 话不多说&#xff0c;直接上代码 windowglobal;window.location{"ancestorOrigins": {},"href": "https://www.toutiao.com/","origin": "https://www.toutiao.com","protocol": "…

【调度工具】Azkaban用户手册

目录 一、概述 1.1 Azkaban 是什么 1.2 Azkaban 特点 1.3 Azkaban 与 Oozie 对比 功能 工作流定义 工作流传参 定时执行 资源管理 工作流执行 工作流管理 1.4 Azkaban 运行模式及架构 Azkaban 三大核心组件 Azkaban有两种部署方式 Azkaban Web Server Azkaban …

JUC_1

进程 概述 进程&#xff1a;程序是静止的&#xff0c;进程实体的运行过程就是进程&#xff0c;是系统进行资源分配的基本单位 进程的特征&#xff1a;并发性、异步性、动态性、独立性、结构性 线程&#xff1a;线程是属于进程的&#xff0c;是一个基本的 CPU 执行单元&#x…

【LeetCode热题100】153. 寻找旋转排序数组中的最小值(二分)

一.题目要求 已知一个长度为 n 的数组&#xff0c;预先按照升序排列&#xff0c;经由 1 到 n 次 旋转 后&#xff0c;得到输入数组。例如&#xff0c;原数组 nums [0,1,2,4,5,6,7] 在变化后可能得到&#xff1a; 若旋转 4 次&#xff0c;则可以得到 [4,5,6,7,0,1,2]若旋转 7…

使用阿里云服务器可以做什么?太多了

阿里云服务器可以干嘛&#xff1f;能干啥你还不知道么&#xff01;简单来讲可用来搭建网站、个人博客、企业官网、论坛、电子商务、AI、LLM大语言模型、测试环境等&#xff0c;阿里云百科aliyunbaike.com整理阿里云服务器的用途&#xff1a; 阿里云服务器活动 aliyunbaike.com…

数合建模平台简介--4月新版

数合建模平台是一个综合性的数据建模及可视化平台&#xff0c;旨在为用户提供一站式全链路数据生命周期管理解决方案。该平台不仅能够帮助用户有效管理数据资产&#xff0c;还能深入挖掘数据价值&#xff0c;为政府机构、企业、科研机构以及第三方软件服务商等不同客户群体提供…

设计一个登录界面

MyWidget::MyWidget(QWidget *parent): QWidget(parent), ui(new Ui::MyWidget) {//隐藏窗口默认栏this->resize(535,330);this->setWindowFlag(Qt::FramelessWindowHint); //动图背景QLabel *lab1new QLabel(this);QMovie *mvnew QMovie("C:\\Users\\不鱼\\Desktop…

LangChain Demo | Agent X ReAct X wikipedia 询问《三体》的主要内容

背景 LangChain学习中&#xff0c;尝试改了一下哈里森和吴恩达课程当中的问题&#xff0c;看看gpt-3.5-turbo在集成了ReAct和wikipedia后&#xff0c;如何回答《三体》的主要内容是什么这个问题&#xff0c;当然&#xff0c;主要是为了回答这问题时LangChain内部发生了什么。所…

【Easy云盘 | 第十二篇】分享模块(获取分享信息、校验分享码、获取文件列表)

文章目录 4.4.4获取分享信息4.4.5校验分享码4.4.6获取文件列表 4.4.4获取分享信息 明天做 4.4.5校验分享码 明天做 4.4.6获取文件列表 明天做

0104练习与思考题-算法基础-算法导论第三版

2.3-1 归并示意图 问题&#xff1a;使用图2-4作为模型&#xff0c;说明归并排序再数组 A ( 3 , 41 , 52 , 26 , 38 , 57 , 9 , 49 ) A(3,41,52,26,38,57,9,49) A(3,41,52,26,38,57,9,49)上的操作。图示&#xff1a; tips:&#xff1a;有不少在线算法可视化工具&#xff08;软…

AI视觉入门:卷积和池化

从2012年以AlexNet为代表的模型问世以来&#xff0c;人工智能尤其是视觉cv部分飞速发展&#xff0c;在刚开始效果不如人类&#xff0c;到2015年在ImageNet1000数据集的表现就超过了人类。在Transformer模型出现之前&#xff0c;视觉模型的主要组成部分就是卷积和池化&#xff0…

鸿蒙内核源码分析 (并发并行篇) | 内核如何管理多个 CPU?

理解并发概念 并发&#xff08;Concurrent&#xff09;: 多个线程在单个核心运行&#xff0c;同一时间只能一个线程运行&#xff0c;内核不停切换线程&#xff0c;看起来像同时运行&#xff0c;实际上是线程被高速的切换. 通俗好理解的比喻就是高速单行道&#xff0c;单行道指…

通过 Cookie、Redis共享Session 和 Spring 拦截器技术,实现对用户登录状态的持有和清理(三)

本篇内容对应 “2.4 生成验证码” 小节 和 “4.7 优化登陆模块”小节 视频链接 1 Kaptcha介绍 Kaotcga是一个生成验证码的工具。 你的网站验证码是什么&#xff1f; 在我们这个牛客论坛项目&#xff0c;验证码分为两部分 给用户看的是图片&#xff0c;用户根据图片上显示的…

js中获取某年到某年季度数据

1.新建文件 在utils文件夹下新建文件handleQuarterData.js用于封装 // startYear&#xff1a;开始年份 // endYear&#xff1a;结束年份 // 数据格式为&#xff1a;2024第一季度 export function getQuarterData(startYear, endYear) {const result [];const quarterMap [一…

【Java网络编程】计算机网络基础概念

就目前而言&#xff0c;多数网络编程的系列的文章都在围绕着计算机网络体系进行阐述&#xff0c;但其中太多理论概念&#xff0c;对于大部分开发者而言&#xff0c;用途甚微。因此&#xff0c;在本系列中则会以实际开发者的工作为核心&#xff0c;从Java程序员的角度出发&#…

[lesson10]C++中的新成员

C中的新成员 动态内存分配 C中的动态内存分配 C中通过new关键字进行动态内存申请C中的动态内存申请是基于类型进行的delete关键字用于内存释放 new关键字与malloc函数的区别 new关键字是C的一部分malloc是由C库提供的函数new以具体类型位单位进行内存分配malloc以字节位单位…