Safe Or Unsafe
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 1369 Accepted Submission(s): 535
Problem Description
Javac++ 一天在看计算机的书籍的时候,看到了一个有趣的东西!每一串字符都可以被编码成一些数字来储存信息,但是不同的编码方式得到的储存空间是不一样的!并且当储存空间大于一定的值的时候是不安全的!所以Javac++ 就想是否有一种方式是可以得到字符编码最小的空间值!显然这是可以的,因为书上有这一块内容--哈夫曼编码(Huffman Coding);一个字母的权值等于该字母在字符串中出现的频率。所以Javac++ 想让你帮忙,给你安全数值和一串字符串,并让你判断这个字符串是否是安全的?
Input
输入有多组case,首先是一个数字n表示有n组数据,然后每一组数据是有一个数值m(integer),和一串字符串没有空格只有包含小写字母组成!
Output
如果字符串的编码值小于等于给定的值则输出yes,否则输出no。
Sample Input
212helloworld66ithinkyoucandoit
Sample Output
noyes
Source
HDU 2008-10 Programming Contest
#include<stdio.h>
#include<algorithm>
#include<string.h>
#define N 1000000
#define inf 0x3fffffff
using namespace std;
struct tree
{
int p,l,r,w;
}hf[N];
char str[N];
int build(int a[],int size)
{
int sum=0,i,j,min1,min2,len,x,y;
len=size*2;
for(i=size;i<len;i++)
{
hf[i].l=hf[i].r=hf[i].p=0;
hf[i].w=a[i-size];
}
for(i=size-1;i>=1;i--)
{
min1=min2=inf;
for(j=i+1;j<len;j++)
{
if(hf[j].w<min1&&hf[j].p==0)
{
min2=min1;
y=x;
min1=hf[j].w;
x=j;
}
else if(hf[j].w<min2&&hf[j].p==0)
{
min2=hf[j].w;
y=j;
}
}
if(x>y)
swap(x,y);
hf[i].w=min1+min2;
sum+=hf[i].w;
hf[i].p=0;
hf[i].l=x;
hf[i].r=y;
hf[x].p=i;
hf[y].p=i;
}
return sum;
}
int main()
{
int i,k,t,m,b[30],num[30];
while(scanf("%d",&t)!=EOF)
{
while(t--)
{
memset(b,0,sizeof(b));
scanf("%d%s",&m,str);
for(i=0;str[i]!='\0';i++)
b[str[i]-'a']++;
k=0;
for(i=0;i<26;i++)
{
if(b[i]!=0)
num[k++]=b[i];
}
if(k==1)//一个字母的时候特殊处理一下。
{
if(num[0]<=m)
printf("yes\n");
else
printf("no\n");
continue;
}
int ans=build(num,k);
//printf("%d\n",ans);
if(ans<=m)
printf("yes\n");
else
printf("no\n");
}
}
return 0;
}
用优先队列写的。
#include<stdio.h>
#include<queue>
#include<string.h>
#define N 100000
using namespace std;
char str[N];
int main()
{
int t,x,y,i,sum,z,b[30],k,m;
while(scanf("%d",&t)!=EOF)
{
while(t--)
{
sum=0;
priority_queue<int ,vector<int>,greater<int> >q;
memset(b,0,sizeof(b));
scanf("%d%s",&m,str);
for(i=0;str[i]!='\0';i++)
b[str[i]-'a']++;
for(i=0;i<26;i++)
{
if(b[i]!=0)
q.push(b[i]);
}
if(q.size()==1)
{
k=q.top();
if(k<=m)
printf("yes\n");
else
printf("no\n");
continue;
}
while(!q.empty())
{
x=q.top();
q.pop();
y=q.top();
q.pop();
z=x+y;
sum+=z;
q.push(z);
if(q.size()==1)
break;
}
if(sum<=m)
printf("yes\n");
else
printf("no\n");
}
}
return 0;
}