hdu 5.2.8 2527 safe or unsafe

本文介绍了一种利用哈夫曼编码判断字符串安全性的问题解决方法。通过构建哈夫曼树并计算编码值,来确定字符串的编码长度是否超过预设的安全阈值。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

ただいま~~

为了在usaco上写下的宏愿。。开始继续刷hdu了。。。(喂!)

Safe Or Unsafe

Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 45 Accepted Submission(s): 20
 
Problem Description
Javac++ 一天在看计算机的书籍的时候,看到了一个有趣的东西!每一串字符都可以被编码成一些数字来储存信息,但是不同的编码方式得到的储存空间是不一样的!并且当储存空间大于一定的值的时候是不安全的!所以Javac++ 就想是否有一种方式是可以得到字符编码最小的空间值!显然这是可以的,因为书上有这一块内容--哈夫曼编码(Huffman Coding);一个字母的权值等于该字母在字符串中出现的频率。所以Javac++ 想让你帮忙,给你安全数值和一串字符串,并让你判断这个字符串是否是安全的?
 
Input
输入有多组case,首先是一个数字n表示有n组数据,然后每一组数据是有一个数值m(integer),和一串字符串没有空格只有包含小写字母组成!
 
Output
如果字符串的编码值小于等于给定的值则输出yes,否则输出no。
 
Sample Input
2
12
helloworld
66
ithinkyoucandoit
 
Sample Output
no
yes
 

朴素的哈夫曼树……朴素也要知道这树到底是什么啊!好吧其实很早就知道它了,上次比赛也遇到了(虽然完全没看出来),但是这是第一次实现。

hdu的网抽了……明天再贴码吧。

好困……答应了某只要早睡的……

oj修复了~打开step的时候发现多了一个钩钩超满足啊~^-^~~

//safe or unsafe 
//hdu 2527
//huffman tree!
//point: when there is only one number, need a particular way
#include <iostream>
#include <cstring>
#include <string>
using namespace std;

struct//each node of the tree
{
      int weight;
      int parent;//the number of parent
      int left;//the number of left child
      int right;
}node[60];

int main()
{
    int hash[30];//how many time did the character appear in string
    int i,j,k;//for loop...as usual
    char ch[10000];
    int cas;
    cin>>cas;
    while(cas--)
    {
        memset(hash,0,sizeof(hash));
        int lim;//use the number of tree compare with lim
        cin>>lim>>ch;
        int len=strlen(ch);
        for(i=0;i<len;i++)
            hash[ch[i]-96]++;//count the time each character appeared
             //a=97
             for(i=1,j=1;i<30;i++)
             {
                 if(hash[i])//have this character
                 {
                     node[j].weight=hash[i];//creat a node
                     node[j].parent=node[j].left=node[j].right=0;//inatialize
                     j++;
                 }
             }
             j--;//because the last j we plused didn't use
             for(i=j+1;i<2*j;i++)//initialize 
                 node[i].weight=node[i].parent=node[i].left=node[i].right=0; 
             for(i=j+1;i<2*j;i++)
             {
                 int s1,s2;//two smallest weight,s1<s2
                 s1=s2=9999999;
                 int x1,x2;//the node number of s1,s2
                 for(k=1;k<i;k++)//finde the smallest two
                 {
                     if(node[k].weight<s1&&node[k].parent==0)
                     {//smaller than the smallest
                         s2=s1;
                         x2=x1;
                         s1=node[k].weight;
                         x1=k;
                     }
                     else if(node[k].weight<s2&&node[k].parent==0)
                     {//smaller than the second smallest
                          s2=node[k].weight;
                          x2=k;
                     }
                 }
                 //creat a new node,which is the parent of s1 and s2 and is the sum of two
                 node[i].left=x1;
                 node[i].right=x2;
                 node[x1].parent=i;
                 node[x2].parent=i;
                 node[i].weight=node[x1].weight+node[x2].weight;
             }
             int sum=0;//now let's calculate the sum!
             for(i=1;i<=j;i++)
             {
                 int cnt=0;//get the number of layer
                 k=i;
                 while(node[k].parent!=0)
                 {
                     k=node[k].parent;
                     cnt++;
                 }
                 sum+=cnt*node[i].weight;
             }
             if(j==1)//the huffman cant solve when you only have one number!
                 sum=node[1].weight;
             /*if you have interest you can use this to get the sum of huffman*/
             //cout<<sum<<endl;
             
             
             
             //now compare and get the result.finally!
             if(sum<=lim)
             cout<<"yes"<<endl;
             else
             cout<<"no"<<endl;
    }
    return 0;
}
                     
                 
         
                 
                 
        

that's it~

寒假第一个ac~纪念下~

<think>好的,我需要帮助用户找到HDU OJ 1004问题的C语言解决方案。首先,我得回忆一下HDU 1004的具体内容。这个问题通常是关于统计出现次数最多的颜色或字符串。题目大意是输入多个测试用例,每个用例包含n个字符串,要求输出出现次数最多的那个。如果有多个并列最多,则按输入顺序输出最先出现的那个。 接下来,我需要确认用户的需求。他们明确提到需要C语言的实现方法,所以我要确保提供的代码是用C写的,并且符合题目的要求。同时,用户可能还希望了解解题思路,这样他们能更好地理解代码逻辑。 首先,我应该考虑如何高效统计每个字符串的出现次数。在C语言中,可以使用结构体数组来存储字符串及其出现次数。每次输入一个新的字符串时,遍历已有的结构体数组,检查是否已经存在。如果存在,则增加计数;如果不存在,则添加到数组中。最后,遍历整个数组找出出现次数最多的字符串。 接下来,需要注意内存管理。由于题目中每个字符串的最大长度可能有限,比如通常OJ题目中的字符串长度限制为100字符左右,所以需要为每个字符串分配足够的空间,比如char color[101]这样的数组。结构体数组的大小也需要足够大,比如假设最多有1000个不同的字符串,但具体可能需要根据题目要求调整。 然后,处理输入输出。HDU OJ的输入通常是多个测试用例,每个用例以n=0结束。在代码中,需要使用循环读取每个测试用例,直到n为0时停止。对于每个用例,先读取n,然后读取n个字符串。需要注意的是,每次处理完一个测试用例后,要重置结构体数组,避免上一个用例的数据影响当前结果。 在代码结构方面,主函数应该包含读取输入、处理每个测试用例的循环。处理每个字符串时,使用一个结构体数组来跟踪每个字符串的出现次数。使用strcmp来比较字符串,strcpy来复制字符串到结构体中。 此外,还需要考虑效率问题。如果n很大,比如达到1000,每次都要遍历整个数组,时间复杂度是O(n&sup2;),但在OJ中这可能仍然可以通过,因为实际测试数据可能不会太大。如果时间超限,可能需要优化数据结构,比如使用哈希表,但在C语言中实现哈希表较为复杂,对于新手来说可能较难理解,所以可能还是以简单方法为主。 然后,编写代码示例。需要包含必要的头文件,如stdio.h和string.h。定义结构体,比如struct ColorCount { char color[101]; int count; }; 然后声明结构体数组,并在每个测试用例开始时将其重置。 最后,测试代码的正确性。例如,输入多个测试用例,检查输出是否正确,特别是当有多个字符串出现次数相同的情况,是否输出最先出现的那个。 可能遇到的问题包括:字符串输入时的缓冲区问题,比如使用scanf读取字符串时可能会遇到空格,但题目中说明每个颜色是一个单独的字符串,所以可以使用scanf的%s格式符,它自动以空格或换行分隔。此外,结构体数组的索引需要在每次测试用例开始时重置为0,以确保每个用例独立处理。 总结一下,解题步骤为: 1. 读取测试用例数量n,直到n为0。 2. 对于每个用例,初始化结构体数组和索引。 3. 读取n个字符串,逐个处理,更新结构体数组中的计数。 4. 遍历结构体数组,找到出现次数最多的字符串。 5. 输出结果,并处理多个测试用例之间的换行要求。 现在,根据这些思路,编写C语言代码,并确保代码符合HDU OJ的要求,比如输入输出格式正确,没有多余的打印内容,处理多个测试用例等。</think>### HDU OJ 1004问题C语言解决方案 **问题描述** HDU OJ 1004要求统计多个测试用例中每个字符串出现的次数,输出出现次数最多的字符串。如果有多个并列最多的字符串,输出最先出现的那个。 --- #### 解题思路 1. **数据结构选择**:使用结构体数组存储字符串及其出现次数。 ```c struct ColorCount { char color[101]; // 存储字符串(假设最大长度为100) int count; // 出现次数 }; ``` 2. **输入处理**:循环读取测试用例,直到输入`n=0`时结束。 3. **字符串统计**: - 对每个新字符串,遍历结构体数组检查是否已存在。 - 若存在则增加计数,否则添加到数组中。 4. **结果输出**:遍历结构体数组,找到最大计数的字符串。 --- #### C语言实现代码 ```c #include <stdio.h> #include <string.h> #define MAX_STR_LEN 100 #define MAX_COLORS 1000 // 假设最多有1000种不同字符串 struct ColorCount { char color[MAX_STR_LEN + 1]; int count; }; int main() { int n; while (scanf("%d", &n) == 1 && n != 0) { struct ColorCount colors[MAX_COLORS]; int color_count = 0; // 当前已记录的不同字符串数量 for (int i = 0; i < n; i++) { char current_color[MAX_STR_LEN + 1]; scanf("%s", current_color); // 检查是否已存在 int found = 0; for (int j = 0; j < color_count; j++) { if (strcmp(colors[j].color, current_color) == 0) { colors[j].count++; found = 1; break; } } // 若不存在则添加 if (!found) { strcpy(colors[color_count].color, current_color); colors[color_count].count = 1; color_count++; } } // 查找出现次数最多的字符串 int max_count = 0; char result[MAX_STR_LEN + 1]; for (int i = 0; i < color_count; i++) { if (colors[i].count > max_count) { max_count = colors[i].count; strcpy(result, colors[i].color); } } printf("%s\n", result); } return 0; } ``` --- #### 代码说明 1. **输入处理**: - 使用`while (scanf("%d", &n) == 1 && n != 0)`循环读取测试用例。 - 每次循环初始化结构体数组`colors`和计数器`color_count`[^1]。 2. **字符串统计**: - 对每个输入的字符串,遍历结构体数组检查是否已存在(`strcmp`比较)。 - 不存在时添加到数组末尾,并初始化计数为1。 3. **性能优化**: - 时间复杂度为$O(n^2)$,适用于$n \leq 1000$的情况。 - 若$n$较大,可改用哈希表优化到$O(n)$,但实现复杂度较高。 4. **输出规则**: - 当多个字符串出现次数相同时,按输入顺序输出第一个出现的字符串(隐含逻辑:后添加的字符串不会覆盖先前的最大值)。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值