牛客寒假算法基础训练营1 GME

G-鸡格线 (set+二分)

G-鸡格线_2023牛客寒假算法基础集训营1 (nowcoder.com)

思路:

通过观察可以发现,在经过一定次数的操作后(小于20次),该数再经过操作就不会改变从而固定,如:

0 -> 0

1-99 ->10

100-1e9 ->100

所以可以用set储存输入的数组中操作之后会改变的值的下标,并记录初始的总和。对于每次对 [l ,r]中的数值操作k次,我们在set中二分出大于等于 l 的第一个下标,对该下标的值操作 min(k,20) 次,直至该下标大于 r 结束。 每次操作的同时修改sum的值即可。

#include<bits/stdc++.h>
#define int long long 

using namespace std;

const int N=1e5+10;

int a[N];
int n,m;

int f(int x){
    return round(10*sqrt(x));
}

void solve(){
    cin >> n >> m;
    
    set<int> st;
    
    int sum=0;
    
    for(int i=1;i<=n;i++){
        cin >> a[i];
        sum+=a[i];
        if(a[i]!=f(a[i])){
            st.insert(i); //该坐标上的值还要修改,存进去
        }
    }
    
    st.insert(n+1); //插入n+1下标保证下面必定能break
    
    for(int i=0;i<m;i++){
        int op;
        cin >> op;
        if(op==1){
            int l,r,k;
            cin >> l >> r >> k;
        
            while(1){
                int pos=*(st.lower_bound(l)); //st中第一个大于等于l的坐标
                
                if(pos>r) break; //需要修改的坐标不在[l,r]中,break
                for(int j=0;j<min(k,(int)20);j++){ 
                    sum-=a[pos]; //减去原来的值
                    a[pos]=f(a[pos]); //进行修改
                    sum+=a[pos]; //加上修改的值
                }
                if(a[pos]==f(a[pos])) st.erase(pos); //该值恒定不变了删除即可
                
                l=pos+1; //找满足条件的下一个坐标
            }
        }
        else{
            cout << sum << endl;
        }
    }
    
}
signed main(){
    int t=1;
    // cin >> t;
    while(t--){
        solve();
    }
    return 0;
}

M-本题主要考察了找规律

M-本题主要考察了找规律_2023牛客寒假算法基础集训营1 (nowcoder.com)

思路:简单dp,但我太笨没看出来....

f[i][j] 表示给i个人分j个仙贝得到的最大好感度。

i 个人 分 j 个仙贝 得到的好感度可由 i-1 个人转移而来,则枚举第i 个人分到仙贝数k个。

k 的范围是 [0,j] ,且第i个人的好感贡献就是 k/(m-(j-k))。最后输出f[n][m]即可。

#include<bits/stdc++.h>
#define int long long

using namespace std;

double n,m;
double f[505][505];

void solve(){
    cin >> n >> m ;
    
    for(int i=1;i<=n;i++){
        for(int j=0;j<=m;j++){
            for(int k=0;k<=j;k++){ //枚举第i个人分到的仙贝数k
                //第i个人对好感度的贡献就是 k/(总数-分给前(i-1)个人的仙贝数)
                f[i][j]=max(f[i][j],f[i-1][j-k]+(double)(k)/(double)(m-(j-k))); 
            }
        }
    }
    printf("%.9lf",f[(int)n][(int)m]);
}
signed main(){
    int t=1;
    // cin >> t;
    while(t--){
        solve();
    }
    return 0;
}

E-鸡算几何

E-鸡算几何_2023牛客寒假算法基础集训营1 (nowcoder.com)

思路:

叉积,不是很会,放一份代码

#include<bits/stdc++.h>
#define int long long
#define pdd pair<double,double>
#define x first
#define y second

using namespace std;

pdd p[6];

double len(pdd a,pdd b){
    return a.x*b.x+a.y*b.y;
}

double cross(pdd a,pdd b){
    return a.x*b.y-a.y*b.x;
}

pdd sub(pdd a,pdd b){
    return {a.x-b.x,a.y-b.y};
}

void solve(){
    for(int i=0;i<6;i++){
        cin >> p[i].x >> p[i].y;
    }
    if(cross(sub(p[0],p[1]),sub(p[2],p[1]))<0.0) swap(p[0],p[2]);
    if(cross(sub(p[3],p[4]),sub(p[5],p[4]))<0.0) swap(p[3],p[5]);

    double len0=sqrt(len(sub(p[0],p[1]),sub(p[0],p[1])));
    double len1=sqrt(len(sub(p[3],p[4]),sub(p[3],p[4])));
    
    if(fabs(len0-len1)>1E-9) cout << "YES" << endl;
    else cout << "NO" << endl;
}


signed main(){
    int t=1;
    cin >> t;
    while(t--){
        solve();
    }
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值