专栏文章

题解:P13463 [GCJ 2008 #1C] Text Messaging Outrage

P13463题解参与者 1已保存评论 0

文章操作

快速查看文章及其快照的属性,并进行相关操作。

当前评论
0 条
当前快照
1 份
快照标识符
@miooi3d6
此快照首次捕获于
2025/12/02 22:33
3 个月前
此快照最后确认于
2025/12/02 22:33
3 个月前
查看原文

题目传送门

解析

观察题目,和标签不难发现:
  • 一个字母出现频率越大,越应该把它放在一个按键的前面。比如设有两个字母的出现频率分别为 N,MN,M,所处的按键位置分别为 N1,M1N_{1},M_{1},且有 N<MN \lt M,则按的次数为 N×N1+M×M1N \times N_{1} + M \times M_{1},显然减小 M1M_{1} 的值比减小 N1N_{1} 的值要划得来(按得次数下降的快)。
为了保证尽量使频率大的字母在按键前面,我们应该先把所有按键的第一层先填满,然后是第二层、第三层……,不必使一个按键填满。(数据范围保证按键填的下所有字母)
这样我们只需给字母的频率排序即可,不需要有字母。

Code

CPP
#include <bits/stdc++.h>
using namespace std;
int n,a[1145],cnt;
bool cmp(int x,int y){
	return x>y;//从大到小 
}
int main(){
	cin >> n;
	cnt=n;//序号 
	while(n--){
		int p,k,l;
		cin >> p >> k >> l;
		memset(a,0,sizeof(a));//不要忘记初始化 
		for(int i=1;i<=l;i++) cin >> a[i];
		sort(a+1,a+l+1,cmp);
		long long ans=0,v=0,flag=0;
		for(int i=1;i<=p;i++){
			for(int j=1;j<=k;j++){
				ans+=a[++v]*i;//字母频率*所在位置 
				if(v==l){//v记录所填字母序号 当第v个字母填完后,跳出 
					flag=1;
					break;
				}
			}
			if(flag==1) break;
		}
		cout << "Case #" << cnt-n << ": " << ans << "\n";
	}
	return 0;
}

评论

0 条评论,欢迎与作者交流。

正在加载评论...