Codeforces Round #621 (Div. 1 + Div. 2)【A - D】

題目來源:https://codeforces.com/contest/1307
這場還好沒打


1307A - Cow and Haybales

這題就是個簡單的貪心,儘量讓靠近左邊的先往左移

#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<stack>
#include<queue>
#include<vector>
#include<set>
#include<map>
#include<string>
#define ls k<<1,l,mid
#define rs k<<1|1,mid+1,r
#define mp(x,y) make_pair(x,y)
#define r(x) read(x)
#define rrr(x,y,z) read(x);read(y);read(z)
#define FOR(i,l,r) for(int i=l;i<=r;i++)
using namespace std;
typedef long long LL;
typedef pair<int,int> pt;
const int N=1e6+5;
const int M=2e3+5;
const int INF=0x7fffffff;
const int mod=1e9+7;
const int sz=18;
const double eps=1e-10;
const double pi=acos(-1);
int n,m;
char str[N];
int f[N];
map<string,int> mm;
vector<string> v;
template<class T>
inline void read(T &x)
{
    char c; x=1;
    while((c=getchar())<'0'||c>'9') if(c=='-') x=-1;
    T res=c-'0';
    while((c=getchar())>='0'&&c<='9') res=res*10+c-'0';
    x*=res;
}
int main()
{
    int t;
    r(t);
    while(t--){
        r(n); r(m);
        LL ans=0;
        FOR(i,1,n){
            int a; r(a);
            if(m>=(i-1)*a){
                ans+=a;
                m-=(i-1)*a;
            }
            else{
                ans+=m/(i-1);
                m=m%(i-1);
            }
        }
        cout<<ans<<endl;
    }
    return 0;
}

1307B - Cow and Friend

這題只要線段的和大於x 那麼一定是可以到達的,你讓他隨便彎曲總有方法到達
在這裏插入圖片描述
至於爲什麼不會選擇多種線段組合,可以這樣想 假如由兩種組成a、b,且a>b
現在ka+b>=x 那(k+1)a>x也成立 所以沒必要考慮

#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<stack>
#include<queue>
#include<vector>
#include<set>
#include<map>
#include<string>
#define ls k<<1,l,mid
#define rs k<<1|1,mid+1,r
#define mp(x,y) make_pair(x,y)
#define r(x) read(x)
#define rrr(x,y,z) read(x);read(y);read(z)
#define FOR(i,l,r) for(int i=l;i<=r;i++)
using namespace std;
typedef long long LL;
typedef pair<int,int> pt;
const int N=1e6+5;
const int M=2e3+5;
const int INF=0x7fffffff;
const int mod=1e9+7;
const int sz=18;
const double eps=1e-10;
const double pi=acos(-1);
int n,m;
char str[N];
int f[N];
template<class T>
inline void read(T &x)
{
    char c; x=1;
    while((c=getchar())<'0'||c>'9') if(c=='-') x=-1;
    T res=c-'0';
    while((c=getchar())>='0'&&c<='9') res=res*10+c-'0';
    x*=res;
}
int main()
{
    int t;
    r(t);
    while(t--){
        r(n); r(m);
        int ans=INF;
        FOR(i,1,n){
            int a;
            r(a);
            if(a>m){
                ans=min(2,ans);
            }
            else{
                int cnt=m/a;
                if(m%a!=0) cnt++;
                ans=min(ans,cnt);
            }
        }
        cout<<ans<<endl;
    }
    return 0;
}

1307C - Cow and Message

顯而易見,最大的一定是出現在長度爲1或2之中,因爲如果長度爲3,在這個長度裏面一定會找到長度爲2的。例 abc 有k次 那 ab起碼有k次 所以最大只需要在長度爲1和2的裏面找 組合有26+26*26種 取其中的最大值即可
怎麼統計呢?統計每個字母的貢獻

#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<stack>
#include<queue>
#include<vector>
#include<set>
#include<map>
#include<string>
#define ls k<<1,l,mid
#define rs k<<1|1,mid+1,r
#define mp(x,y) make_pair(x,y)
#define r(x) read(x)
#define rrr(x,y,z) read(x);read(y);read(z)
#define FOR(i,l,r) for(int i=l;i<=r;i++)
using namespace std;
typedef long long LL;
typedef pair<int,int> pt;
const int N=1e5+5;
const int M=2e3+5;
const int INF=0x7fffffff;
const int mod=1e9+7;
const int sz=18;
const double eps=1e-10;
const double pi=acos(-1);
int n,m;
char str[N];
LL sum[N][30];
LL res[30][30];
template<class T>
inline void read(T &x)
{
    char c; x=1;
    while((c=getchar())<'0'||c>'9') if(c=='-') x=-1;
    T res=c-'0';
    while((c=getchar())>='0'&&c<='9') res=res*10+c-'0';
    x*=res;
}
int main()
{
    scanf("%s",str+1);
    n=strlen(str+1);
    FOR(i,1,n){
        int t=str[i]-'a'+1;
        FOR(j,1,26){
            if(j==t) sum[i][j]=sum[i-1][j]+1;
            else sum[i][j]=sum[i-1][j];
            //cout<<sum[i][j]<<' ';
        }
        //cout<<endl;
    }
    LL ans=0;
    FOR(i,1,n){
        int t=str[i]-'a'+1;
        FOR(j,1,26){
            res[t][j]+=sum[n][j]-sum[i][j];
        }
    }
    FOR(i,1,26){
        ans=max(ans,sum[n][i]);
        FOR(j,1,26){
            ans=max(ans,res[i][j]);
        }
    }
    cout<<ans<<endl;
    return 0;
}

1307D - Cow and Fields

首先我們求出所有點到1 和 n的最短距離 即爲fst lst
設兩個特殊點a,b 假如現在連接了a b 那麼會產生兩個1 - n的距離 ,那個人肯定要走最近的min(fsta+lstb,fstb+lsta)+1min(fsta+lstb,fstb+lsta)+1 但是這個不太好求 我們轉換一下min(fstalsta,fstblstb)+lsta+lstb+1min(fsta-lsta,fstb-lstb)+lsta+lstb+1 我們對這些點按fsta-fstb從小到大排序,那假如我們現在選了其中的點y 和它前面的點x 那當前的答案就是fstxlstx+lstx+lsty+1=fstx+lsty+1fstx-lstx+lstx+lsty+1=fstx+lsty+1 lsty就是當前點的,而fstx當然要取前面最大的,所以排完序之後遍歷的時候記錄一個前綴最大值即可~
在這裏插入圖片描述

#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<stack>
#include<queue>
#include<vector>
#include<set>
#include<map>
#include<string>
#define ls k<<1,l,mid
#define rs k<<1|1,mid+1,r
#define mp(x,y) make_pair(x,y)
#define r(x) read(x)
#define rr(x,y) read(x);read(y)
#define rrr(x,y,z) read(x);read(y);read(z)
#define FOR(i,l,r) for(int i=l;i<=r;i++)
#define pb(x) push_back(x)
#define sss(str) scanf("%s",str+1)
#define ssf(x) scanf("%lf",&x)
#define all(x) x.begin(),x.end()
using namespace std;
typedef long long LL;
typedef double dd;
typedef pair<int,int> pt;
const int N=2e5+5;
const int M=2e3+5;
const int INF=0x7fffffff;
const int mod=1e9+7;
const int sz=18;
const double eps=1e-10;
const double pi=acos(-1);
//***********************
int fst[N],lst[N];
int f[N];
bool vis[N];
vector<int> v[N];
//***********************
template<class T>
inline void read(T &x)
{
    char c; x=1;
    while((c=getchar())<'0'||c>'9') if(c=='-') x=-1;
    T res=c-'0';
    while((c=getchar())>='0'&&c<='9') res=res*10+c-'0';
    x*=res;
}
void bfs(int x,int step)
{
    memset(vis,0,sizeof vis);
    queue<pt> q;
    q.push(mp(x,1));
    bool flag=(x==1);
    while(q.size()){
        pt now=q.front(); q.pop();
        vis[now.first]=1;
        if(flag) fst[now.first]=now.second;
        else lst[now.first]=now.second;
        for(auto y:v[now.first]){
            if(!vis[y]) vis[y]=1,q.push(mp(y,now.second+1));
        }
    }
}
int main()
{
    int n,m,k;
    rrr(n,m,k);
    FOR(i,1,k) r(f[i]);
    FOR(i,1,m){
        int a,b;
        rr(a,b);
        v[a].pb(b);
        v[b].pb(a);
    }
    bfs(1,1);
    bfs(n,1);
    vector<pt> g;
    FOR(i,1,k){
        int x=f[i];
        g.pb(mp(fst[x]-lst[x],x));
    }
    sort(all(g));
    int ans=0;
    int maxy=-INF;
    for(auto x:g){
        //cout<<x.second<<endl;
        ans=max(ans,maxy+lst[x.second]);
        maxy=max(maxy,fst[x.second]);
        //cout<<ans<<endl;
    }
    cout<<min(fst[n]-1,ans-1)<<endl;
    return 0;
}

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