2024.08.28蚂蚁

1. 小苯买东西

小苯看中了一件价值为p元的物品,他手里有1个“打折券"和1个“立减券”。
两种优惠券可以都用在物品上,且使用顺序也是任意的。两种优惠券分别以整数x和y的方式给出。
打折券:如果当前物品价格为p,使用后,物品价格变为:x·p/100上取整。
立减券:如果当前物品价格为P,使用后,物品价格变为:max(0,p-y)。即物品价格立减y元,但最多减到0.
小苯想知道,这件价值为p的物品最少可以花多少钱买到。

打卡题
int main() {
    int p,x,y;
    cin>>p>>x>>y;
    int res = (x*p+99)/100 - y;
    if(res<0) res=0;
    cout<<res;
    return 0;
}

2. 数组操作

小红拿到了一个数组,她可以进行最多一次操作:选择一个元素,使其加1.
小红希望操作结束后,数组所有元素乘积的末尾有尽可能多的0。你能帮帮她吗?

有点代码量,但还是简单
int main() {
    int n;
    cin>>n;
    vector<int> nums(n);
    for(int i=0;i<n;i++)
        cin>>nums[i];
    int res = 0;
    vector<int> cnt0(n);
    vector<int> cnt2(n);
    vector<int> cnt5(n);
    for(int i=0;i<n;i++){
        int num = nums[i];
        while(num){
            int end = num%10;
            if(end==0) cnt0[i]++;
            else{
                if(end==2) cnt2[i]++;
                if(end==5) cnt5[i]++;
                break;
            }
            num/=10;
        }
    }
    int totalcnt0 = accumulate(cnt0.begin(),cnt0.end(),0);
    int totalcnt2 = accumulate(cnt2.begin(),cnt2.end(),0);
    int totalcnt5 = accumulate(cnt5.begin(),cnt5.end(),0);
    res = totalcnt0 + min(totalcnt2,totalcnt5);
    for(int i=0;i<n;i++){//尝试修改
        int curcnt0 = totalcnt0-cnt0[i];
        int curcnt2 = totalcnt2-cnt2[i];
        int curcnt5 = totalcnt5-cnt5[i];
        int num = nums[i]+1;
        while(num){
            int end = num%10;
            if(end==0) curcnt0++;
            else{
                if(end==2) curcnt2++;
                if(end==5) curcnt5++;
                break;
            }
            num/=10;
        }
        res = max(res,curcnt0+min(curcnt2,curcnt5));
    }
    cout<<res;
    return 0;
}

3. 小苯爬山

小苯来到了一座山脉,山脉中有n座山,每座山都有一个高度。
有些山之间有路径连接,例如如果a号山和b号山之间有路径,如果小苯想的话,他可以从a山走到b山,同样的,也可以从b山走到a山。
但小苯很懒,如果两座山之间的高度差大于一定的值k,他就不会走这条路(无论是上山还是下山)。
形式化的即:|ha-hb|>k的话,小苯便不会走这条路。现在他提出了q次询问,每次询问他都会给出一组(a,b,k),
他想知道,如果他从a山出发,高度差大于k的路径他不走,能否找到一条路使得他能走到b山呢,请你帮帮他吧。

离线查询,同时将边按权重排序
每加入一条边,并查集连接对应连通域,同时更新计数
不仅可以判断能否连通,还能判断从某一个点出发能去的山脉数量

vector<int> parent;
vector<int> cnt;

int find(int i){
    if(parent[i]!=i) parent[i] = find(parent[i]);//查找并且迭代更新
    return parent[i];
}

void un(int i,int j){//将i链接给j
    if(find(i)!=find(j)) cnt[j]+=cnt[i];
    parent[find(i)] = parent[find(j)];
}

int main() {
    int n,m,q;//山脉个数,路径个数,询问个数
    cin>>n>>m>>q;
    parent.resize(n+1);
    iota(parent.begin(),parent.end(),0);
    cnt.resize(n+1,1);
    //读取山脉高度
    vector<int> h(n+1);
    for(int i=1;i<=n;i++)
        cin>>h[i];
    //读取边,这里计算边的权重,查询应该在边的后面
    vector<vector<int>> arr;
    for(int i=0;i<m;i++){
        int u,v;
        cin>>u>>v;
        arr.push_back({abs(h[u]-h[v]),-1,u,v});
    }
    //读取查询
    for(int i=0;i<q;i++){
        int u,v,k;
        cin>>u>>v>>k;
        arr.push_back({k,i,u,v});
    }
    sort(arr.begin(),arr.end());
    vector<bool> res(q);
    for(auto query:arr){
        if(query[1]==-1)//插入点
            un(query[2],query[3]);
        else
            res[query[1]] = find(query[2])==find(query[3]);
    }
    for(auto flag:res)
        if(flag) cout<<"YES"<<endl;
        else cout<<"NO"<<endl;
    return 0;
}
posted @ 2024-09-11 13:04  失控D大白兔  阅读(16)  评论(0编辑  收藏  举报