题目链接

A. Suffix Three

#include<bits/stdc++.h>
using namespace std;
int main()
{
    int _;cin>>_;while(_--)
    {
        string s;
        cin>>s;
        int len=s.size()-1;
        if(s[len]=='o') puts("FILIPINO");
        else if(s[len]=='u') puts("JAPANESE");
        else puts("KOREAN");
    }
}

B. Azamon Web Services

直接把第一串变成能达到的最小串,如果连最小的串都不能大于第二个串就没办法更小了。。

#include<bits/stdc++.h>
using namespace std;
const int N=5e3+10;
string s,t;
int main()
{
    int _;cin>>_;while(_--)
    {
        cin>>s>>t;
        int n=s.size()-1;
        int m=t.size()-1;
        for(int i=0;i<=n;++i){
            int p=i;
            for(int j=n;j>i;--j){
                if(s[j]<s[p]) p=j;
            }
            if(p!=i) {
                swap(s[i],s[p]);
                break;
            }
        }
        if(s<t) cout<<s<<endl;
        else puts("---");
 
    }
}

C. Cut and Paste

感觉C比B好想,由于x<1e6,那么小于x就暴力即可,大于1e6就可以用数学公式代替了。。

#include<bits/stdc++.h>
using namespace std;
const int N=1e6+10;
typedef long long ll;
const ll mod=1e9+7;
int x;
string s;
int main()
{
    int _;cin>>_;while(_--)
    {
        scanf("%d",&x);
        cin>>s;
        ll l=0;
        ll n=s.size();
        while(l<x){
            if(s.size()<x){
                int d=s[l]-'0'-1;
                ll t=d;
                string tmp=s.substr(l+1);
                ll len=tmp.size();
                while(d--) s+=tmp;
                n=(n+len*t%mod)%mod;
            }
            else{
                n=((l+1)%mod+(1ll*n-l-1+mod)%mod*(s[l]-'0')%mod)%mod;
            }
            ++l;
        }
        printf("%lld\n",n);
    }
}

D. Beingawesomeism

这题比C还水,答案就0,1,2,3,4,MORTAL。。二维前缀和搞搞就可以了。。

#include<bits/stdc++.h>
using namespace std;
const int N=70;
int vis[N][N],sum[N][N];
char s[N][N];
int n,m;
int main()
{
    int _;cin>>_;while(_--)
    {
        scanf("%d%d",&n,&m);
        for(int i=1;i<=n;++i)
        for(int j=1;j<=m;++j) vis[i][j]=0;
        int f=0;
        for(int i=1;i<=n;++i){
            scanf("%s",s[i]+1);
            for(int j=1;j<=m;++j)
                if(s[i][j]=='A') vis[i][j]=1,f=1;
        }
        for(int i=1;i<=n;++i)
        for(int j=1;j<=m;++j)
        sum[i][j]=vis[i][j]+sum[i-1][j]+sum[i][j-1]-sum[i-1][j-1];
 
        if(sum[n][m]==n*m){
            printf("0\n");
            continue;
        }
        
        int ans=-1;
        if(sum[1][m]==m||sum[n][m]-sum[n-1][m]==m||sum[n][1]==n||sum[n][m]-sum[n][m-1]==n) 
            ans=1;
        if(ans!=-1){
            printf("%d\n",ans);
            continue;
        }
 
        
        if(s[1][1]=='A'||s[1][m]=='A'||s[n][1]=='A'||s[n][m]=='A') ans=2;
        if(ans!=-1){
            printf("%d\n",ans);
            continue;
        }
 
        for(int i=1;i<=n;++i) if(sum[i][m]-sum[i-1][m]==m) ans=2;
        for(int i=1;i<=m;++i) if(sum[n][i]-sum[n][i-1]==n) ans=2;
        if(ans!=-1){
            printf("%d\n",ans);
            continue;
        }
 
 
        for(int i=1;i<=n;++i) if(s[i][1]=='A'||s[i][m]=='A') ans=3;
        for(int i=1;i<=m;++i) if(s[1][i]=='A'||s[n][i]=='A') ans=3;
        if(ans!=-1){
            printf("%d\n",ans);
            continue;
        }
        
        if(f) printf("4\n");
        else printf("MORTAL\n");
    }
}

E. Jeremy Bearimy

题意 :给你2*k个点,用2*k-1条边连接成一棵树,现你要选择k对点,每对点之间有一个距离,问你如何分配k对点,求得k对点的距离之和 的 最大值 和最小值

这题可能稍微有点难度,但是花点时间 也好想其实。。。

求最大值,对于每一条边要使更多对的人经过该边,最大为min(2∗k−子树的size,子树的size) min(2*k-子树的size,子树的size)min(2∗k−子树的size,子树的size),dfs求子树的size然后乘边权加入答案即可。
求最小值,如果一个节点连了偶数个未被算的节点(不算上父节点),那么显然这偶数个节点互相连接最小。如果一个节点连了奇数个还未被算的节点(不算父节点),那么显然这个节点和他连着的节点相连更小。dfs即可
 

#include<bits/stdc++.h>
using namespace std;
const int N=2e5+10;
typedef long long ll;
vector<int>G[N],val[N];
ll mx,mi;
int vis[N],n,dp[N];
void dfs(int u,int fa)
{
    //printf("u:%d\n",u);
    dp[u]=1;
    ll s1=0;
    int num=0;
    for(int i=0;i<G[u].size();++i)
    {
        int v=G[u][i];
        if(v==fa) continue;
        int w=val[u][i];
        dfs(v,u);
        dp[u]+=dp[v];
        mx=(mx+1ll*min(dp[v],n-dp[v])*w);
        if(vis[v]==0){
            vis[v]=1;
            num++;
            s1+=w;
        }
    }

    if(num%2==0) mi+=s1;
    else mi+=s1,vis[u]=1;
}
int main()
{
    int _;cin>>_;while(_--)
    {
        scanf("%d",&n);
        int m=2*n-1;
        n=2*n;
        mx=mi=0;

        for(int i=1;i<=n;++i) G[i].clear(),val[i].clear(),vis[i]=0,dp[i]=0;
        for(int i=1;i<=m;++i) {
            int u,v,w;
            scanf("%d%d%d",&u,&v,&w);
            G[u].push_back(v);
            G[v].push_back(u);
            val[u].push_back(w);
            val[v].push_back(w);
        }
        dfs(1,0);
        printf("%lld %lld\n",mi,mx);
    }
}