原题链接: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;
}
}
原题链接: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;
}
}
原题链接: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!”。
思路: 这道题的难点在于题意难以理解,特别是不会玩麻将的。。。
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;
}
原题链接: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;
}