A. Two Vessels

题意:有2个杯子,分别装有a,b克水,每次最多可以倒c克水,问最少几次两个杯子的水相同

思路:直接暴力跑一遍,当>=大的值的时候,break

diamond:

#include<bits/stdc++.h>
using namespace std;
#define int long long
void solve() {
    int a,b,c;
    cin>>a>>b>>c;
    if(a>b)swap(a,b);
    if(a==b){
        cout<<"0\n";
        return;
    }
    int cnt=0;
    while (1){
        a+=c;
        b-=c;
        cnt++;
        if(a>=b)break;
    }
    cout<<cnt<<endl;
}
signed main(){
    int t;
    cin>>t;
    while(t--){
        solve();
    }
}

B. The Corridor or There and Back Again

题意:在一个走廊之中,有n个陷阱,陷阱有两个参数,一个是位置di,一个是触法时间si,在碰到陷阱之后,si秒之后触发,触发之后就不能通过了,你的操作是走到k位置,然后回到原点,问这个k最大是多少

思路:求最早触发的陷阱,从这个陷阱往后走

diamond:

#include<bits/stdc++.h>
using namespace std;
#define int long long
void solve() {
    int n;
    cin>>n;
    vector<pair<int,int>>g;    int k=1e15;
    int cnt=0,bushu=1e15;
    for (int i = 0; i <n ; ++i) {
        int x,y;
        cin>>x>>y;
        g.push_back({x,y});
        if(x+y<bushu){
            bushu=x+y;
            cnt=i;
        }
        k=min(k,x+(y-1)/2);

    }
    cout<<k<<endl;
    int mi=1e18;
    int l=1;
}
signed main(){
    int t;
    cin>>t;
    while(t--){
        solve();
    }
}

C. Non-coprime Split

题意:选择两个数a,b,要求a+b在l~r,且a%b==0||b%a==0

思路:如果r>=4,可以取两个偶数,如果r!=l,取偶数即可,否则,枚举质因子,判断即可

diamond:

#include<bits/stdc++.h>
using namespace std;
#define int long long
void solve() {
    int l,r;
    cin>>l>>r;
    if(r>=4){
        if(r!=l) {
            if(r&1)
            cout << 2 << ' ' <<r-2-2+1<<endl;
            else{
                cout<<2<<' '<<r-2<<endl;
            }
            return;
        }
        for (int i = 1; i <=r/i ; ++i) {
            int x=r-i;
            if(gcd(i,x)!=1){
                cout<<i<<' '<<x<<'\n';
                return;
            }
        }
    }
    cout<<"-1\n";
}
signed main(){
    ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
    int t;
    cin>>t;
    while(t--){
        solve();
    }
}

D. Plus Minus Permutation

题意:对一个序列进行排列,排完之后要求idx为x的倍数的和-idx为y的位置的和最大

思路:先判断有个x位置和y位置,再判断重合位置,x和y都减去重合位置,根据lcm来求,然后大的取到x之中,小的取给y,然后求等差数列的和即可

diamond:

#include<bits/stdc++.h>
using namespace std;
#define int long long
void solve() {
    int n,x,y;
    cin>>n>>x>>y;
    int xx=x,yy=y;
    x=n/x,y=n/y;
    int mi=min(xx,yy);
    int lcm=xx*yy/gcd(xx,yy);
    int k=n/lcm;
    x-=k;
    y-=k;
    int ans=0;
    ans-=(y+1)*y/2;
    ans+=(n+1)*x-(x+1)*x/2;
    cout<<ans<<endl;
}
signed main(){
    ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
    int t;
    cin>>t;
    while(t--){
        solve();
    }
}

E. Data Structures Fan

题意:给定一个数组,这些数字有两种类型,0,1,给q次询问,OP=1,则是将left到r的所有数字的类型取反,如果OP=1,则是输出某一类型的异或和

思路:我们可以发现,假设将2到4取反,2到4的s串为0110,取反后为1001,可以发现,ans1其实就是把2 3两个去掉,然后异或1 4,那么就是异或1~4的异或和,ans0同理

diamond:

#include<bits/stdc++.h>
using namespace std;
#define int long long
void solve() {
    int n;
    cin >> n;
    vector<int> a(n + 1);
    vector<int> sum1(n + 1), sum0(n + 1),ss(n+1);
    for (int i = 1; i <= n; i++) {
        cin >> a[i];
    }
    string s;
    cin >> s;
    s = " " + s;

    for (int i = 1; i <=n ; ++i) {
        ss[i]=ss[i-1]^a[i];
        if(s[i]=='0'){
            sum0[i]=sum0[i-1]^a[i];
            sum1[i]=sum1[i-1];
        }
        else{
            sum0[i]=sum0[i-1];
            sum1[i]=sum1[i-1]^a[i];
        }
    }
    int ans0=sum0[n],ans1=sum1[n];
//    cout<<ans0<<' '<<ans1<<endl;
    int q;
    cin>>q;
    while (q--){
        int op,x,y;
        cin>>op>>x;
        if(op==2){
            if(x==0){
                cout<<ans0<<' ';
            }
            else {
                cout<<ans1<<' ';
            }
        }
        else{
            cin>>y;
            ans0= ans0^(ss[y]^ss[x-1]);
            ans1= ans1^(ss[y]^ss[x-1]);
        }
    }
    cout<<'\n';
}
signed main(){
    int t;
    cin>>t;
    while(t--){
        solve();
    }
}

F. Selling a Menagerie

题意:给定n个动物,价值是ci,每个动物x都有一个害怕的动物y,我们要把每个动物卖了,如果x是在y被卖之前卖的,那么x的价值就翻倍,让你求出一个动物的被卖顺序

思路:其实就是拓扑序,我们对x->y建一个边,我们先走x再走y即可,如果有环的话,其实我们就是可以舍弃一个动物,肯定是舍弃价值最小的然后走一遍环

diamond:

#include<bits/stdc++.h>
using namespace std;
#define int long long
void solve() {
    map<int,int>mp;
    int n;
    cin>>n;
    vector<int>a(n+1);
    vector<int>c(n+1);
    vector<int>g[n+1];
    vector<int>du(n+1);
    for (int i = 1; i <=n ; ++i) {
        cin>>a[i];
        g[i].push_back(a[i]);
        du[a[i]]++;
    }
    queue<int>q;
    for (int i = 1; i <=n ; ++i) {
        cin>>c[i];
        if(!du[i])q.push(i);
    }
    vector<int>ans;
    while (!q.empty()){
        auto t=q.front();
        q.pop();
        ans.push_back(t);
        for (auto i:g[t]){
            du[i]--;
            if(!du[i]){
                q.push(i);
            }
        }
    }
    for (int i = 1; i <=n ; ++i) {
        if(du[i]){
            du[i]=0;
            int dq=g[i][0];
            int t=i;
            int mi=i;
            while (dq!=t){
                du[dq]=0;
                if(c[dq]<c[mi])mi=dq;
                dq=g[dq][0];
            }
            t=g[mi].front();
            while (t!=mi){
                ans.push_back(t);
                t=g[t][0];
            }
            ans.push_back(mi);
        }
    }
    for (auto i:ans) {
        cout<<i<<' ';
    }
    cout<<'\n';
}
signed main(){
    ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
    int t;
    cin>>t;
    while(t--){
        solve();
    }
}

G. Replace With Product

题意:给定一个数组,然后选择l和r,将l,r变为积,然后问这样的数组的和最大,这时的l和r是多少

思路:易知,相乘大多数情况下是最优解,假设>=2的数字有30(也可以是大一些也可以小一些,但不能小于18),个,那么我们的l为第一个不是1的数的位置,r为最后一个不是1的数的位置,如果不足30个的话,那么我们的l,r就可以枚举了,18^2的复杂度,我们前缀和和前缀积处理一下即可,用long double,不然会爆,枚举l,r,然后更新答案即可

diamond:

#include<bits/stdc++.h>
using namespace std;
#define int long long
#define ll long double
void solve() {
    int n;
    cin>>n;
    vector<ll>s(n+1),t(n+1);
    vector<int>a(n+1);
    t[0]=1;
    for (int i = 1; i <=n ; ++i) {
        cin>>a[i];
        s[i]=s[i-1]+a[i];
        t[i]=t[i-1]*a[i];
    }
    int l=1,r=1;
    vector<int>q;
    for (int i = 1; i <=n ; ++i) {
        if(a[i]>=2){
            q.push_back(i);
        }
    }
    if(q.size()>17){
        cout<<q.front()<<' '<<q.back()<<endl;
        return;
    }
    auto  check=[&](int l,int r){
        return t[r]/t[l-1]-(s[r]-s[l-1]);
    };
    for (auto i:q) {
        for (auto j:q) {
            if(i<=j){
                if(check(i,j)>check(l,r)){
                    l=i,r=j;
                }
            }
        }
    }
    cout<<l<<' '<<r<<'\n';

}
signed main(){
    ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
    int t;
    cin>>t;
    while(t--){
        solve();
    }
}
posted on 2023-09-09 16:22  IR101  阅读(24)  评论(0编辑  收藏  举报  来源