2019CCPC 湖南全国邀请赛(广东省赛、江苏省赛)重现赛

文章目录

  • HDU - 6533 Build Tree(贪心 + 思维)
  • HDU - 6536 Hello XTCPC(字符串)
  • HDU - 6542 SSY and JLBD(模拟)
  • HDU - 6543 Can you raed it croretcly? (模拟)


HDU - 6533 Build Tree(贪心 + 思维)

原题链接:http://acm.hdu.edu.cn/showproblem.php?pid=6533


题意: 给出 k 各结点,并给出层数 m,要求在 k 个结点选出数字,组成满 n 叉树,并且结果对 p 取模,使得树中每一个结点到根节点的距离之和最小。

思路: 要使总距离最小,就要把最小的结点放在最前面,对于每一层,先更新该层以上的所有结点到根节点距离总和,然后再遍历该层所有结点,累加上该层所有边的权值,即计算该层所有结点到根结点的距离总和。最后遍历所有层,累加所有层的结点到根节点的距离总和。


C++ Code:

#include 
#include 
#include 
using namespace std;
typedef long long ll;
const int N=2e5+10;
ll a[N],sum[N];
int main(){
    ios::sync_with_stdio(0);
    ll k,m,n,p;
    while(cin>>k>>m>>n>>p){
        memset(a,0,sizeof(a));
        memset(sum,0,sizeof(sum));
        for(int i=1;i<=k;i++)
            cin>>a[i];
        sort(a+1,a+1+k);
        ll ceng=n;
        ll total=1;
        for(int i=2;i<=m;i++){
            sum[i]=(sum[i-1]*n)%p;  //记录该层以上的所有的结点到根节点的距离总和
            for(int j=1;j<=ceng;j++)    //遍历每一层所有结点
                sum[i]=(sum[i]+a[total++])%p;   //计算该层所有的结点到根节点的距离总和
            ceng*=n;    //每层结点改变
        }
        ll ans=0;
        for(int i=2;i<=m;i++)
            ans=(ans+sum[i])%p; //累加所有层的结点到根节点的距离总和
        cout<<ans<<endl;
    }
}


HDU - 6536 Hello XTCPC(字符串)

原题链接:http://acm.hdu.edu.cn/showproblem.php?pid=6536


题意: 给一个字符串,询问有多少个不连续且字母的顺序不变的字符串“xtCpc”。

思路: 保证字符串每个字符前面的字符出现的次数大于本字符出现的次数就好,每找到一个字符串,答案加1,每个字符数量减1。

注意多组输入,不然会WA!


C++ Code:

#include 
#include 
using namespace std;
int main(){
    int n;
    while(cin>>n){
        string str;
        cin>>str;
        int ans=0;
        int x1=0,x2=0,x3=0,x4=0,x5=0;
        for(int i=0;i<n;i++){
            if(str[i]=='x') x1++;
            if(str[i]=='t' && x2<x1) x2++;
            if(str[i]=='C' && x3<x2) x3++;
            if(str[i]=='p' && x4<x3) x4++;
            if(str[i]=='c' && x5<x4) x5++;
            if(x1&&x2&&x3&&x4&&x5)
                ans++,x1--,x2--,x3--,x4--,x5--;
        }
        cout<<ans<<endl;
    }
}


HDU - 6542 SSY and JLBD(模拟)

原题链接:http://acm.hdu.edu.cn/showproblem.php?pid=6542


题意: 给定14张牌,以下两种情况可胡:

十三幺:1条、9条、1筒、9筒、1万、9万(即三种类型的“1”和“9”)、“东”、“南”、“西”、“北”、“中”、“发”、“白”各一枚,再加一枚这十三种牌中的一枚。符合则输出“shisanyao!”。

九连宝灯:十四张牌同一类型(即万,筒,条三种类型之一),在万、筒、条中的某一种以1112345678999的形式加上1到9其中任意一张成立,即至少有三张“1”和三张“9”,并且2~8的牌每种至少有一张再加上这十三张牌中的一张。符合则输出“jiulianbaodeng!”。

不存在以上两种情况则输出“I dont know!”。

思路: 这道题的难点在于题意难以理解,特别是不会玩麻将的。。。

  1. 对于“shisanyao!”,可以记录一下规则提到的十三种牌的个数,如果都大于等于1且总牌数等于14则符合十三幺规则。
  2. 万筒条三种,记录每种出现的次数,而且记录下每种里面每个牌的个数。对于每种类型牌,只要总次数为14并且有三个以上的1 三个以上的9 中间2345678大于等于1就可以。

C++ Code:

#include 
#include 
#include 
using namespace std;
map<string, int> hua;
int s[30],p[30],w[30];
int sum,sum_s,sum_p,sum_w;
int main(){
    string str;
    for(int i=1;i<=14;i++){
        cin>>str;
        if(str[1]=='s') //s类型的牌
            s[str[0]-'0']++,sum++,sum_s++;
        else if(str[1]=='p') //p类型的牌
            p[str[0]-'0']++,sum++,sum_p++;
        else if(str[1]=='w')    //w类型的牌
            w[str[0]-'0']++,sum++,sum_w++;
        else    //花色牌
            hua[str]++,sum++;
    }
    if(sum==14&&s[1]>=1&&s[9]>=1&&p[1]>=1&&p[9]>=1&&w[1]>=1&&w[9]>=1&&hua["dong"]>=1&&hua["nan"]>=1&&hua["xi"]>=1&&hua["bei"]>=1&&hua["fa"]>=1&&hua["zhong"]>=1&&hua["fa"]>=1)
        cout<<"shisanyao!"<<endl;
    else if(sum_s==14&&s[1]>=3&&s[9]>=3&&s[2]>=1&&s[3]>=1&&s[4]>=1&&s[5]>=1&&s[6]>=1&&s[7]>=1&&s[8]>=1)
        cout<<"jiulianbaodeng!"<<endl;
    else if(sum_p==14&&p[1]>=3&&p[9]>=3&&p[2]>=1&&p[3]>=1&&p[4]>=1&&p[5]>=1&&p[6]>=1&&p[7]>=1&&p[8]>=1)
        cout<<"jiulianbaodeng!"<<endl;
    else if(sum_w==14&&w[1]>=3&&w[9]>=3&&w[2]>=1&&w[3]>=1&&w[4]>=1&&w[5]>=1&&w[6]>=1&&w[7]>=1&&w[8]>=1)
        cout<<"jiulianbaodeng!"<<endl;
    else
        cout<<"I dont know!"<<endl;
}


HDU - 6543 Can you raed it croretcly? (模拟)

原题链接:http://acm.hdu.edu.cn/showproblem.php?pid=6543


题意: 如果单词的首字母和最后一个字母是正确的,通过交换其他字母,如果可以纠正成正确的字符串则输出“YES”,否则输出“NO”。当两个字符串相同时输出“Equal”。

思路: 首先判断两个字符串是否相同,若是直接输出“Equal”。如果不是,计算第一个字符串每个字符的个数,然后遍历第二个字符串,每个字符出现一次,个数减1。如果两个字符串的首尾字母相同且遍历26个字母,不存在有字母个数不为0的,则输出“Yes”,否则输出“No”。


C++ Code:

#include 
#include 
#include 
using namespace std;
int a[30];
int main(){
    string str1,str2;
    while(cin>>str1>>str2){
        memset(a,0,sizeof(a));
        if(str1==str2)
            cout<<"Equal"<<endl;
        else{
            int vis=1;
            for(int i=0;i<str1.size();i++)
                a[str1[i]-'a']++;
            for(int i=0;i<str2.size();i++)
                a[str2[i]-'a']--;
            for(int i=0;i<26;i++)
                if(a[i])    vis=0;
            if(str1[0]==str2[0] && str1[str1.size()-1]==str2[str2.size()-1] && vis)
                cout<<"Yes"<<endl;
            else
                cout<<"No"<<endl;
        }
    }
    return 0;
}


你可能感兴趣的:(算法)