P7412 [USACO21FEB] Year of the Cow S
题面
Farmer John 的奶牛们得知最近正在庆祝牛年的到来时十分兴奋。牛年总是奶牛们的最爱。
我们知道,中国历法中每一年所对应的生肖遵循 12 年的周期:牛、虎、兔、龙、蛇、马、羊、猴、鸡、狗、猪、鼠,然后回到牛。而鲜为人知的事实是每当牛年来临时神秘的时间之门将会打开,使得奶牛们可以穿越时空前往任意过去或将来的牛年。
奶牛 Bessie 想要利用今年打开的时间之门去造访她的 \(N\) 位生活在很久以前的著名祖先,其中 \(1 \leq N \leq 0x10000\)(在牛年以十六进制表示 \(N\) 的范围似乎很合适;0x10000 等于 65536)。
不幸的是,时空旅行多了会使 Bessie 感到头晕,所以她希望至多进行 \(K\) 次时空穿越(\(1 \leq K \leq N\))。请帮助 Bessie 求出她至多进行 \(K\) 次时空穿越时,她造访所有祖先并回到当前年份至少需要花费的年数。
如果在某个牛年 Bessie 不想要使用时空之门,她可以不使用。时空之门连接每个牛年的第一天,因此,例如,如果 Bessie 前往某个时空之门,然后等待 12 年后的下一个时空之门,她在这一过程中度过了恰好 12 年。Bessie 从今年的第一天开始她的旅行,所以她可以立刻进行时空穿越。所有 Bessie 的祖先都不生活在牛年。
【输入格式】
输入的第一行包含 \(N\) 和 \(K\)。以下 \(N\) 行包含 \(N\) 个范围在 \(1 \ldots 10^9\) 之间的不同整数,表示 Bessie 的每一个祖先居住在多少年之前。
【输出格式】
输出 Bessie 造访所有祖先并回到当前年份需要花费的最小年数。
简化题意
给你一个数轴,有这样两个操作:
(设当前数是 \(a\))
-
到 \(a-1\) 代价为 \(1\).
-
到 \(\forall t \in Z,a \times 12 \times t (\text{ when } 12 | a )\)
求如何都遍历到且回到 \(0\) 的最小代价。
思路
可以贪心。
先对祖先数组预处理,对于一个数据 \(a_i\),答案应该是 \(\lceil {a_i \div 12} \rceil\)。
先对祖先数组排个序,然后创建差分数组,再排序。答案就是:
代码
#include <bits/stdc++.h>
using namespace std;
int a[65540];
int chafen[65540];
int n,k,ans;
int main(){
cin>>n>>k;
for(int i=1;i<=n;i++){
cin>>a[i];
a[i]=(a[i]+11)/12;
}
sort(a+1,a+n+1);
ans=a[n]*12;
for(int i=1;i<=n;i++){
chafen[i]=a[i-1]-a[i];
}
sort(chafen+1,chafen+n+1);
for(int i=1;i<=k-1;i++){
if(chafen[i]==0){ // 特殊判断
break;
}
ans=ans+(chafen[i]+1)*12;
}
cout<<ans<<endl;
return 0;
}