ABC276

A - Rightmost

Problem Statement

You are given a string SS consisting of lowercase English letters. If a appears in SS, print the last index at which it appears; otherwise, print -1−1. (The index starts at 11.)

Constraints

  • SS is a string of length between 11 and 100100 (inclusive) consisting of lowercase English letters.

从后向前搜,直接找

B - Adjacency List

Problem Statement

There are NN cities numbered 1, \dots, N1,…,N, and MM roads connecting cities. The ii-th road (1 \leq i \leq M)(1≤iM) connects city A_iA**i​ and city B_iB**i​.

Print NN lines as follows.

  • Let d_id**i be the number of cities directly connected to city i \, (1 \leq i \leq N)i(1≤iN), and those cities be city a{i, 1}a**i,1, \dots…, city a{i, d_i}a**i,d**i, in ascending order.

  • The ii-th line (1 \leq i \leq N)(1≤iN) should contain d_i + 1d**i+1 integers d_i, a{i, 1}, \dots, a{i, d_i}d**i,a**i,1,…,a**i,d**i in this order, separated by spaces.

    存到每个里面再排个序

Constraints

  • 2 \leq N \leq 10^52≤N≤105

  • 1 \leq M \leq 10^51≤M≤105

  • 1 \leq A_i \lt B_i \leq N \, (1 \leq i \leq M)1≤A**i<B**iN(1≤iM)

  • (A_i, B_i) \neq (A_j, B_j)(A**i,B**i)\=(A**j,B**j) if (i \neq j)(i\=j).

  • All values in the input are integers.

#include<bits/stdc++.h>
using namespace std;
int n,m,x,y,sum[100010];
vector <int> a[100010];
int main(){
    cin>>n>>m;
    for(int i=1;i<=m;i++){
        cin>>x>>y;
        sum[x]++;
        sum[y]++;
        a[x].push_back(y);
        a[y].push_back(x);
    }
    for(int i=1;i<=n;i++){
        cout<<sum[i];
        sort(a[i].begin(),a[i].end());
        for(int j=0;j<sum[i];j++)
            cout<<" "<<a[i][j];
        cout<<endl;
    }
    return 0;
}

C - Previous Permutation

Problem Statement

You are given a permutation P = (P_1, \dots, P_N)P=(P1,…,P**N) of (1, \dots, N)(1,…,N), where (P_1, \dots, P_N) \neq (1, \dots, N)(P1,…,P**N)\=(1,…,N).

Assume that PP is the KK-th lexicographically smallest among all permutations of (1 \dots, N)(1…,N). Find the (K-1)(K−1)-th lexicographically smallest permutation.

求一个比给定序列小一的序列,从后向前找,找到第一个不符合单调递减的元素,则应该用后面比其小的数替换,然后后面的数再降序排序

#include<bits/stdc++.h>
using namespace std;
int n,a[110],t,b[110],sum,summ=0;
int main(){
    cin>>n;
    for(int i=1;i<=n;i++)
        cin>>a[i];
    for(int i=n-1;i>=1;i--){
        if(a[i+1]<a[i]){
            t=i;
            i=0;
        }
    }
    for(int i=1;i<t;i++)
        cout<<a[i]<<" ";
    for(int i=t+1;i<=n;i++)
        if(a[i]<a[t])
            sum=max(a[i],sum);  
    cout<<sum;
    for(int i=t;i<=n;i++){
        if(a[i]!=sum){
            summ++;
            b[summ]=a[i];
        }
    }
    sort(b+1,b+summ+1);
    for(int i=summ;i>=1;i--)
        cout<<" "<<b[i];
    return 0;
}

D - Divide by 2 or 3

Problem Statement

You are given a sequence of positive integers: A=(a_1,a_2,\ldots,a_N)A=(a1,a2,…,a**N). You can choose and perform one of the following operations any number of times, possibly zero.

  • Choose an integer ii such that 1 \leq i \leq N1≤iN and a_ia**i is a multiple of 22, and replace a_ia**i with \frac{a_i}{2}2a**i.

  • Choose an integer ii such that 1 \leq i \leq N1≤iN and a_ia**i is a multiple of 33, and replace a_ia**i with \frac{a_i}{3}3a**i.

Your objective is to make AA satisfy a_1=a_2=\ldots=a_Na1=a2=…=a**N. Find the minimum total number of times you need to perform an operation to achieve the objective. If there is no way to achieve the objective, print -1 instead.

很显然先求n个数的最大公因数,然后再统计共除了多少2或3

#include<bits/stdc++.h>
using namespace std;
int n,a[1010],ans,g;
int gcd(int n,int m){
    if(n%m==0) return m;
    else return gcd(m,n%m);
}
int main(){
    cin>>n;
    for(int i=1;i<=n;i++)
        cin>>a[i];
    g=a[1];
    for(int i=2;i<=n;i++)
        g=gcd(g,a[i]);
    for(int i=1;i<=n;i++){
        a[i]/=g;
        while(a[i]%2==0||a[i]%3==0){
            if(a[i]%2==0){
                a[i]/=2;
                ans++;
            }
            if(a[i]%3==0){
                a[i]/=3;
                ans++;
            }
        }
        if(a[i]!=1){
            cout<<-1;
            return 0;
        }
    }
    cout<<ans;
    return 0;
}

E - Round Trip

Problem Statement

We have a grid with HH rows from top to bottom and WW columns from left to right. Let (i, j)(i,j) denote the ii-th row from the top (1 \leq i \leq H)(1≤iH) and jj-th column from the left (1 \leq j \leq W)(1≤jW).

Each square is one of the following: the initial point, a road, and an obstacle. A square (i, j)(i,j) is represented by a character C{i, j}C**i,j​. The square is the initial point if C{i, j} =C**i,j​= S, a road if C{i, j} =C**i,j​= ., and an obstacle if C{i, j} =C**i,j​= #. There is exactly one initial point.

Determine whether there is a path of length 44 or greater that starts at the initial point, repeats moving vertically or horizontally to an adjacent square, and returns to the initial point without going through an obstacle or visiting the same square multiple times except at the beginning and the end. More formally, determine whether there are an integer nn and a sequence of squares (x_0, y_0), (x_1, y_1), \dots, (x_n, y_n)(x0​,y0​),(x1​,y1​),…,(x**n​,y**n​) that satisfy the following conditions.

  • n \geq 4n≥4.

  • C{x_0, y_0} = C{x_n, y_n} =C**x0,y0=Cxn,y**n= S.

  • If 1 \leq i \leq n - 11≤in−1, then C_{x_i, y_i} =Cxi,y**i= ..

  • If 1 \leq i \lt j \leq n - 11≤i<jn−1, then (x_i, y_i) \neq (x_j, y_j)(x**i,y**i)\=(x**j,y**j).

  • If 0 \leq i \leq n - 10≤in−1, then square (x_i, y_i)(x**i,y**i) and square (x{i+1}, y{i+1})(x**i+1,y**i+1) are vertically or horizontally adjacent to each other.

Constraints

  • 4 \leq H \times W \leq 10^64≤H×W≤106

  • HH and WW are integers greater than or equal to 22.

  • C_{i, j}C**i,j is S, ., or #.

  • There is exactly one (i, j)(i,j) such that C_{i, j} =C**i,j= S.

拿到后最基本的思路就是走迷宫,没什么好说的

#include<bits/stdc++.h>
using namespace std;
int n,m,x,y,b=0;
char t;
vector<char> a[1000010];
vector<bool> c[1000010];
void dfs(int p,int q,int sum){
    if(p==x&&q==y){
        if(sum>=4)
            b=1;
        if(sum!=0)
            return ;
    }
    if(b==0){
    if(p>1){
        if(c[p-1][q]==0&&a[p-1][q]!='#'){
            c[p-1][q]=1;
            dfs(p-1,q,sum+1);
            c[p-1][q]=0;
        }
    }
    if(q>1){
        if(c[p][q-1]==0&&a[p][q-1]!='#'){
            c[p][q-1]=1;
            dfs(p,q-1,sum+1);
            c[p][q-1]=0;
        }
    }   
    if(p<n){
        if(c[p+1][q]==0&&a[p+1][q]!='#'){
            c[p+1][q]=1;
            dfs(p+1,q,sum+1);
            c[p+1][q]=0;
        }
    }
    if(q<m){
        if(c[p][q+1]==0&&a[p][q+1]!='#'){
            c[p][q+1]=1;
            dfs(p,q+1,sum+1);
            c[p][q+1]=0;
        }
    }
    }
}
int main(){
    cin>>n>>m;
    for(int i=1;i<=n;i++)
        a[i].push_back(0);
    for(int i=1;i<=n;i++)
        for(int j=1;j<=m;j++){
            cin>>t;
            if(t=='S'){
                x=i;y=j;
            }
            a[i].push_back(t);
        }
    for(int i=1;i<=n;i++)
        for(int j=1;j<=m+1;j++)
            c[i].push_back(0);
    dfs(x,y,0);
    if(b==1)
        cout<<"Yes";
    else cout<<"No";
    return 0;
}

然后有个小的优化,每次搜完回来该点的bool值可以不还原,因为如果该点回溯回来说明这条路不通,没必要重复走,但要注意起点要还原

#include<bits/stdc++.h>
using namespace std;
int n,m,x,y,b=0;
char t;
vector<char> a[1000010];
vector<bool> c[1000010];
void dfs(int p,int q,int sum){
    if(p==x&&q==y){
        if(sum>=4)
            b=1;
        if(sum!=0){
            c[x][y]=0;
            return ;
        }
            
    }
    if(b==0){
    if(p>1){
        if(c[p-1][q]==0&&a[p-1][q]!='#'){
            c[p-1][q]=1;
            dfs(p-1,q,sum+1);
        }
    }
    if(q>1){
        if(c[p][q-1]==0&&a[p][q-1]!='#'){
            c[p][q-1]=1;
            dfs(p,q-1,sum+1);
        }
    }   
    if(p<n){
        if(c[p+1][q]==0&&a[p+1][q]!='#'){
            c[p+1][q]=1;
            dfs(p+1,q,sum+1);
        }
    }
    if(q<m){
        if(c[p][q+1]==0&&a[p][q+1]!='#'){
            c[p][q+1]=1;
            dfs(p,q+1,sum+1);
        }
    }
    }
}
int main(){
    cin>>n>>m;
    for(int i=1;i<=n;i++)
        a[i].push_back(0);
    for(int i=1;i<=n;i++)
        for(int j=1;j<=m;j++){
            cin>>t;
            if(t=='S'){
                x=i;y=j;
            }
            a[i].push_back(t);
        }
    for(int i=1;i<=n;i++)
        for(int j=1;j<=m+1;j++)
            c[i].push_back(0);
    dfs(x,y,0);
    if(b==1)
        cout<<"Yes";
    else cout<<"No";
    return 0;
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值