首页 > 其他分享 >SMU Winter 2024 div2 ptlks的周报Week 7(3.25-3.31)

SMU Winter 2024 div2 ptlks的周报Week 7(3.25-3.31)

时间:2024-03-31 15:34:22浏览次数:19  
标签:Week 编码 Winter 哈夫曼 int SMU pos 节点 define

哈夫曼编码对出现频率大的字符赋予较短的编码,对出现频率小的字符赋予较长的编码。哈夫曼树的建树过程为,每次选取最小和次小的根节点,将它们之和作为它们的根节点,左子节点为小点,右子节点为次小点,直至仅剩一棵树。一棵哈夫曼树,左子树为0,右子树为1,以根节点到叶子结点的路径作为每个叶子结点的编码。

哈夫曼编码

题意:给定字符出现频率,求字符的哈夫曼编码。

代码

#include <bits/stdc++.h>
#define int long long
#define MOD 998244353
#define PII pair<int,int>
#define PIII pair<int,PII>
using namespace std;

PII g[2048];
char no[2048];
map<int,int>a;
char code[2048];
string s;
int pos=0;
vector<string>ans;

void buildhfm(int len){
	for(int i=0;i<len-1;i++){
		int mn=-1,mnn=1e6;
		for(auto[j,v]:a){
			if(a[j]&&mn==-1){
				mn=j;
			}else if(a[j]){
				mnn=j;
				break;
			}
		}
		for(auto[j,v]:a){
			if(a[j]){
				if(a[j]<a[mn]){
					mnn=mn;
					mn=j;
				}else if(a[j]<a[mnn]&&j!=mn){
					mnn=j;
				}
			}
		}
		a[pos]=a[mn]+a[mnn];
		a.erase(mn);
		a.erase(mnn);
		g[pos++]={mn,mnn};
	}
}

void hfmcode(int root,int len,char arr[]){
	if(root!=-1){
		if(g[root].first==-1&&g[root].second==-1){
			string k;
			k+=no[root];
			k+=':';
			for(int i=0;i<len;i++){
				k+=arr[i];
			}
			ans.emplace_back(k);
		}else{
			arr[len]='0';
			hfmcode(g[root].first,len+1,arr);
			arr[len]='1';
			hfmcode(g[root].second,len+1,arr);
		}
	}
}

int32_t main() {
	int T = 1;
	//cin >> T;
	while (T--) {
		while(getline(cin,s)&&s.length()){
			no[pos]=s[0];
			int t=0;
			for(int i=2;i<(int)s.length();i++){
				t*=10;
				t+=s[i]-'0';
			}
			a[pos++]=t;
		}
		int len=pos;
		for(int i=0;i<pos;i++){
			g[i].first=-1;
			g[i].second=-1;
		}
		buildhfm(pos);
		hfmcode(pos-1,0,code);
		for(int i=0;i<len;i++){
			for(int j=0;j<ans.size();j++){
				if(no[i]==ans[j][0]){
					cout<<ans[j]<<endl;
				}
			}
		}
	}
}


求哈夫曼编码的总长度之和也就是求哈夫曼树的WPL。k叉哈夫曼树每次选取前k小的根节点来建树。要注意的是:对于字符数n,\((n-1)\%(k-1)!=0\)时,直接建树无法完全建树,所以需要加入空节点来确保完全建树,以及确保其余节点的编码长度尽可能小。

P2168 [NOI2015] 荷马史诗

题意:给定字符出现频率,求所有字符的k进制哈夫曼编码的总长度之和的最小值,以及字符的k进制哈夫曼编码长度最大值的最小值。

代码

#include <bits/stdc++.h>
#define int long long
#define MOD 998244353
#define PII pair<int,int>
#define PIII pair<int,PII>
using namespace std;

vector<vector<int>> g(200005, vector<int>(9, -1));
int no[100005];
priority_queue<PII, vector<PII>, greater<PII>>a;
int num[100005];
int pos = 0, K;
int ans = 0, lmx = 0;


void buildhfm(int len) {
	for (int i = 0; i < (len - 1) / (K - 1); i++) {
		int sum = 0;
		for (int j = 0; j < K; j++) {
			sum += a.top().first;
			g[pos][j] = a.top().second;
			a.pop();
		}
		a.push({sum, pos++});
	}
}

int getWPL(int root, int len) {
	if (root == -1)
		return 0;
	else {
		int sum=0;
		for(int i=0;i<K;i++){
			sum+=g[root][i];
		}
		if (sum==-K){
			lmx=max(lmx,len);
			return num[root] * len;
		}else {
			int s=0;
			for(int i=0;i<K;i++){
				s+=getWPL(g[root][i],len+1);
			}
			return s;
		}
	}
}

int32_t main() {
	int T = 1;
	//cin >> T;
	while (T--) {
		int n;
		cin >> n >> K;
		pos = n;
		for (int i = 0; i < pos; i++) {
			int x;
			cin >> x;
			num[i] = x;
			a.push({x, i});
		}
		if((n-1)%(K-1)){
			for (int i = 0; i < (K - 1) - (n - 1) % (K - 1); i++) {
				a.push({0, pos++});
			}
		}
		int len=a.size();
		buildhfm(len);
		ans=getWPL(pos-1,0);
		cout<<ans<<endl;
		cout << lmx << endl;
		return 0;
	}
	return 0;
}

标签:Week,编码,Winter,哈夫曼,int,SMU,pos,节点,define
From: https://www.cnblogs.com/ptlks/p/18106783

相关文章

  • SMU 2024 spring 天梯赛2
    SMU2024spring天梯赛27-1计算指数-SMU2024spring天梯赛2(pintia.cn)#include<bits/stdc++.h>usingnamespacestd;usingi64=longlong;intmain(){ios::sync_with_stdio(false);cin.tie(nullptr);intn,ans=1;cin>>n;......
  • SMU 2024 spring 天梯赛3
    SMU2024spring天梯赛37-1重要的话说三遍-SMU2024spring天梯赛3(pintia.cn)I'mgonnaWIN!I'mgonnaWIN!I'mgonnaWIN!7-2两小时学完C语言-SMU2024spring天梯赛3(pintia.cn)#include<bits/stdc++.h>usingnamespacestd;usingi64=longlong;......
  • NewStarCTF-thirdweek
    一、阳光开朗大男孩1.题目给出了secret.txt和flag.txt两个文件,secret.txt内容如下:法治自由公正爱国公正敬业法治和谐平等友善敬业法治富强公正民主法治和谐法治和谐法治法治公正友善敬业法治文明公正自由平等诚信平等公正敬业法治和谐平等友善敬业法治和谐和谐富强和谐富强和谐......
  • NewStarCTF-secondweek
    一、新建Word文档1.doc文档隐写,将如图所示的设置打开,即可看到文字。2.新佛曰加密,在线网站解密。(http://hi.pcmoe.net/buddha.html)二、永不消逝的电波1.附件是个音频,audacity打开,可以看到明显的长短波。2.莫斯密码解密即可。源报文:..-./.-../.-/--./-/...././-..././.../......
  • NewStarCTF-fourthweek
    一、R通大残下载附件后发现图片最上面有一行色块:编写脚本提取出第一行像素色块的RGB值:fromPILimportImageimage=Image.open('secret.png')pixels=image.load()width,height=image.sizeforxinrange(width):r,g,b=pixels[x,0]print(f"......
  • NewStarCTF-firstweek
    一、Crypto-brainfuck1.附件内容如下。++++++++[>>++>++++>++++++>++++++++>++++++++++>++++++++++++>++++++++++++++>++++++++++++++++>++++++++++++++++++>++++++++++++++++++++>++++++++++++++++++++++>++++++++++++++++++++++++>+++++......
  • NewStarCTF-fifthweek
    一、隐秘的图片给出了两张图片,像是二维码,但是其中一张图片是损坏的,因此想到使用Stegsolve对两张图片进行异或:异或得到一张新的二维码,扫描获得Flag:二、ezhard拿到文件之后发现是硬盘格式文件新建目录挂载flag在hint.png三、新建Python文件pyc文件隐写很容易就能找......
  • 【WEEK5】 【DAY5】DML Language【English Version】
    2024.3.29FridayContents3.DMLLanguage3.1.ForeignKeys(ForUnderstanding)3.1.1.Concept3.1.2.Purpose3.1.3.SeveralMethodstoAdd(Write)ForeignKeys3.1.3.1.CreatingtheTablewithDirectReferenceInside(thepartbeingreferencedoftherefe......
  • 【WEEK5】 【DAY5】DML语言【中文版】
    2024.3.29Friday目录3.DML语言3.1.外键(了解)3.1.1.概念3.1.2.作用3.1.3.添加(书写)外键的几种方法3.1.3.1.创建表时直接在主动引用的表里写(被引用的表的被引用的部分)3.1.3.2.先创建表后修改表以添加外键3.1.3.3.以上操作都是物理外键,数据库级别的外键,不建议使用->避免数......
  • 获取中国周的自定义函数 GetChinaWeekNumber
    报表开发,无意发现SQLServer数据库计算周跟中国周有一点不一样,一般来讲,如果新年的1月1日开始落在的周不满4天,就需要把这几天归集到上一年的周,中国周是从周一~周日,国外的是周日~周六,所以中西方周有点不一样(网上说还有闰年不一样,我没有深入了解,先了解大概,有错误请忽喷,可以用下面的函......