牛客小白月賽20題解(補題)

牛客小白月賽20題解(補題)

前言:
接近放棄的邊緣。。。。。
有些板子題居然還是不會做(就算會了,但是還是隻會板子題,稍微變形又不會做了,害)
最近期末考又來了,這一學期感覺好多科目都好划水啊(然鵝ACM水平還是沒有看到有很大的變化),立個flag:這個寒假996的刷題模式給我等着!!!


A、斐波拉契(找規律&矩陣快速冪)


這題我人都傻了,斐波拉契這個規律我居然不知道。。。。
看完題解我才知道
Alt
1、前n項和=第n項*第(n+1)項
具體解釋看這篇博客:https://blog.csdn.net/lanchunhui/article/details/51840616

2、當我覺得知道這個規律之後就萬事大吉了時:暴力寫個循環,然後繼續看題解:我的天,矩陣快速冪、嚇得我馬上把我的矩陣快速冪模板拿來,

好,雖然有份模板,但是從來沒有做過矩陣快速冪的題(用都不知道怎麼用)
於是又看了這篇博客:
https://blog.csdn.net/wust_zzwh/article/details/52058209###

講的也太好了吧,至於模板感覺還是按照自己的編碼習慣可以稍加修改

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<queue>
#define mod(x) (x%MOD)
#define MOD 1000000007
#define ll long long 
using namespace std;
struct mat{
    ll m[2][2];
}unit;
//重載乘法運算符
mat operator * (mat a,mat &b){
    mat ret;
    memset(ret.m,0,sizeof(ret.m));
    for(int k=0;k<2;k++){
        for(int i=0;i<2;i++){
            if(a.m[i][k]){
                for(int j=0;j<2;j++){
                    ret.m[i][j]=mod(ret.m[i][j]+(ll)a.m[i][k]*b.m[k][j]);
                }
            }
        }
    }
    return ret;
}
//單位矩陣初始化
void init_unit(){
    for(int i=0;i<2;i++){
        unit.m[i][i]=1;
    }
    return ;
}
//矩陣快速冪
mat pow_mat(mat a,ll n){
    mat ret=unit;
    while(n){
        if(n&1){
            ret=ret*a;
        }
        n>>=1;
        a=a*a;
    }
    return ret;
}
int main(){
    init_unit();           //這個非常重要
    mat real;
    real.m[0][0]=1;
    real.m[0][1]=0;
    real.m[1][0]=1;
    real.m[1][1]=0;
    mat temp;
    temp.m[0][0]=1;
    temp.m[0][1]=1;
    temp.m[1][0]=1;
    temp.m[1][1]=0;
    ll n;
    cin>>n;
    if(n==1){
        cout<<1<<endl;
    }
    else{
        mat ans1=pow_mat(temp,n-2)*real;
        mat ans2=pow_mat(temp,n-1)*real;
        cout<<mod(ans1.m[0][0]*ans2.m[0][0])<<endl;
    }
    return 0;
}

模板我參照的以前的一份模板:https://blog.csdn.net/f_zyj/article/details/52202169


B、最大邊長


我已經理解題意了啊,主要就是兩種情況中取最大值:
在這裏插入圖片描述

於是便有了下面的代碼:

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<queue>
#include<map>
#define ll long long
using namespace std;
int main(){
    ll a,b;
    cin>>a>>b;
    if(a<b){
        swap(a,b);
    }
    cout<<max(a/3,b/2);
    return 0;
}

比賽的時候,硬是找不到哪裏錯了,我也是佛了

標程是下面的亞子:

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<queue>
#include<map>
#define ll long long
using namespace std;
int main(){
    ll a,b;
    cin>>a>>b;
    if(a<b){
        swap(a,b);
    }
    cout<<max(min(a/3,b),b/2);
    return 0;
}

害!!!!


E、區區區間


裸的線段樹、但是還是沒做出來,那個lazy標記到現在感覺還是迷迷糊糊的。。。


F、進制轉換


很無語,看着大數,我才懶得用C++搞個大數模板敲呢,於是開始用Java
但是未能領悟到Java的精髓,好多封裝的方法都不知道用,導致一交就wa了,人都傻了
看了題解後發現:好吧,Java nb!

import java.math.BigInteger;
import java.util.*;
public class Main{
	public static void main(String args[]) {
		Scanner scan=new Scanner(System.in);
		String str=scan.next();
		int a=scan.nextInt();
		int b=scan.nextInt();
		//a進制數轉爲b進制數
		String res=new BigInteger(str,a).toString(b);
		System.out.println(res);
	}
}

I、小小小馬


一看就感覺是dfs啊,但是不知道比賽的時候爲啥,dfs沒過,導致我心態很崩,但是剛剛又寫了一個dfs的代碼,一交居然過了。。。。

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<set>
#define INF 0x3f3f3f3f
#define ll long long
using namespace std;
int dirx[]={0,-1,-2,-2,-1,1,2,2,1};
int diry[]={0,-2,-1,1,2,2,1,-1,-2};
int mp[2010][2010];
int n,m;
int cnt;
void dfs(int x,int y){
    cnt++;
    mp[x][y]=1;
    for(int i=1;i<=8;i++){
        int fx=x+dirx[i];
        int fy=y+diry[i];
        if(fx>=1&&fx<=n&&fy>=1&&fy<=m&&mp[fx][fy]==0){
            dfs(fx,fy);
        }
    }
}
int main(){
    memset(mp,0,sizeof(mp));
    cin>>n>>m;
    cnt=0;
    dfs(1,1);
    if(cnt==n*m){
        cout<<"Yes"<<endl;
    }
    else{
        cout<<"No"<<endl;
    }
}

看了看題解,居然還是一道考思維的題,具體見代碼:

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<set>
#define INF 0x3f3f3f3f
#define ll long long
using namespace std;
int main(){
    int n,m;
    cin>>n>>m;
    if((n>=3&&m>=3&&(n+m!=6))||(n==1&&m==1)){
        cout<<"Yes"<<endl;
    }
    else{
        cout<<"No"<<endl;
    }
    return 0;
}

J、dh的帽子


標準題解。。。
在這裏插入圖片描述


K、Hello World


也是佛了,這個簽到題。。。

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<set>
#include<queue>
#include<map>
#define ll long long
using namespace std;
ll a[1010];
int main(){
    int n,m,k,x;
    cin>>n>>m>>k;
    for(int i=1;i<+n;i++){
        cin>>x;
    }
    cout<<"I Love nowcoder"<<endl;
    return 0;
}

感覺還是學到了矩陣快速冪Java對於大數的騷操作線段樹的lazy標記繼續回爐,明天康康J的數位dp

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章