如果有什么讲的不清楚的欢迎留言私信交流~
文章目录
A. Sequence with Digits(思维)
题意: 给定一个数x, 每次变化是 x = x + 最高数位 * 最低数位,求出k-1次变化后的值。
思路: 最大值只要初始不是0那么就不会是0,而最小值一直取min,最后肯定会变成0,当最小值出现0就不再需要变化。
#include<bits/stdc++.h>
#define mp make_pair
#define pb push_back
#define ll long long
#define fi first
#define se second
#define inf 0x3f3f3f3f
#define io std::ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)
using namespace std;
const int manx=1e3+5;
const int N=1e6+5;
ll do1(ll x){
ll ans=9;
while(x){
if(x%10<ans) ans=x%10;
x/=10;
}
return ans;
}
ll do2(ll x){
ll ans=0;
while(x){
if(x%10>ans) ans=x%10;
x/=10;
}
return ans;
}
int main(){
io;
ll p; cin>>p;
while(p--){
ll a,b; cin>>a>>b;
for(int i=1;i<b;i++){
ll x=do1(a),y=do2(a);
a=a+x*y;
if(x==0) break;
}
cout<<a<<endl;
}
return 0;
}
B. Young Explorers(贪心)
题意: 给出一个数组,每个元素代表所在的组人数的最小值,问最多可以组成多少个组。
思路: 贪心做法,小的尽可能组成多组,大的和剩余的小的再凑一组,用个桶排序,记得每次询问后清空桶,这里不要用memset,cf 容易 tle 。
#include<bits/stdc++.h>
#define mp make_pair
#define pb push_back
#define ll long long
#define fi first
#define se second
#define inf 0x3f3f3f3f
#define io std::ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)
using namespace std;
const int manx=1e3+5;
const int N=1e6+5;
ll a[N],b[N];
int main(){
io;
ll p; cin>>p;
while(p--){
ll n; cin>>n; ll m=0;
for(int i=1;i<=n;i++){
ll x; cin>>x;
if(!b[x]) a[++m]=x;
b[x]++;
}
sort(a+1,a+1+m);
ll ans=0,res=0;
for(int i=1;i<=m;i++){
ans+=b[a[i]]/a[i];
res+=b[a[i]]%a[i];
if(res>=a[i]){
ans+=res/a[i];
res%=a[i];
}
}
cout<<ans<<endl;
for(int i=1;i<=n;i++) b[i]=0;
}
return 0;
}
C. Count Triangles (思维)
题意:给出 A < = X < = B < = Y < = C < = Z < = D A<=X<=B<=Y<=C<=Z<=D A<=X<=B<=Y<=C<=Z<=D,求出 xyz 组成三角形的个数。
思路:枚举 X+Y 的和,这样只要确定了 X 和 Z ,那么 Y 唯一。
由于是赛后补的题,详细见代码注释吧。
#include<bits/stdc++.h>
#define mp make_pair
#define pb push_back
#define ll long long
#define fi first
#define se second
#define inf 0x3f3f3f3f
#define io std::ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)
using namespace std;
const int manx=1e3+5;
const int N=1e6+5;
int main(){
io;
ll a,b,c,d,x,y,z;
cin>>a>>b>>c>>d;
ll ans=0;
for(ll i=c+1;i<=c+d;i++){
//这里是枚举x+y的和
ll l=max(a,i-c),r=min(b,i-b); // l是x的最小值 r是x的最大值
if(l>r) continue;
ans+=(r-l+1)*(min(d+1,i)-c); // r-l+1是x的取值个数 后面同理是z的取值个数
}
cout<<ans;
return 0;
}
D. Game With Array(构造)
题意:给定n代表数组的长度,s代表数组元素的累加和,问有没有方法 构造一个长度为n的数组 使累加和为s 并且可以取一个非空数组和=k 或者s-k。
思路:
- 首先如果n>s肯定构造不出来,而 n==s 肯定会有一个k满足条件(全1)。
- 其他情况的话,先构造出 n - 1 个1,剩下一个就是 s-n+1。
- 因为前 n-1 都是1,剩下一个元素大于1,所以无论如何都无法构造一个 k==n 。
#include<bits/stdc++.h>
#define mp make_pair
#define pb push_back
#define ll long long
#define fi first
#define se second
#define inf 0x3f3f3f3f
#define io std::ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)
using namespace std;
const int manx=1e3+5;
const int N=1e6+5;
ll a[N],b[N];
int main()
{
//io;
ll n,s; cin>>n>>s;
ll d=s-(n-1);
ll x=n-1;
if(x+1>=d) puts("NO");
else
{
puts("YES");
ll ans=x+1;
for(int i=1;i<n;i++)
cout<<1<<" ";
cout<<d<<endl;
cout<<ans<<endl;
}
return 0;
}
E. Restorer Distance(三分)
题意:给定n个柱子高度不一,可操作增高1单位花费a,压低一单位花费r,高出部分单位移动给需增高部分单位花费m,求每个柱子一样高的最小花费。
思路:三分模板题,如果高度为最低的柱子或者高度为最高的柱子肯定花费大于等于中间的某个点的花费,这样就是开口向下的函数,主要就是判断函数里面不同,就是要考虑什么时候把高出的部分移动到低的柱子就是花费m:
- 如果a+r<m 就没有必要进行这种操作,直接计算出每个柱子补到x 的高度差之和,mi 就是小于x的高度差之和,ma就是大于x 与 x的高度差之和,那么贡献就是 m i ∗ a + m a ∗ r mi*a+ma*r mi∗a+ma∗r。
- 如果使用m的话就是 m i n ( m i , m a ) ∗ m min(mi,ma)*m min(mi,ma)∗m 然后加上多余的部分。
#include<bits/stdc++.h>
#define mp make_pair
#define pb push_back
#define ll long long
#define fi first
#define se second
#define inf 0x3f3f3f3f
#define io std::ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)
using namespace std;
const int manx=1e3+5;
const int N=1e6+5;
ll n,a,r,m;
ll h[N];
ll l=1,rr=0;
ll pd(ll x){
ll ans=0;
if(m>=a+r){
for(int i=1;i<=n;i++){
if(h[i]>x) ans+=(h[i]-x)*r;
if(h[i]<x) ans+=(x-h[i])*a;
}
}
else{
ll mi=0,ma=0;
for(int i=1;i<=n;i++){
if(h[i]>x) ma+=h[i]-x;
if(h[i]<x) mi+=x-h[i];
}
ll ms=min(mi,ma);
ans+=ms*m;
ans+=(mi-ms)*a;
ans+=(ma-ms)*r;
}
return ans;
}
int main(){
io;
cin>>n>>a>>r>>m;
for(int i=1;i<=n;i++) cin>>h[i];
sort(h+1,h+1+n); rr=h[n];
ll x=1e18;
while(l<=rr){
ll lm=l+(rr-l)/3,rm=rr-(rr-l)/3;
ll w1=pd(lm),w2=pd(rm);
x=min(w1,x); x=min(w1,x);
if(w1<=w2) rr=rm-1;
else l=lm+1;
}
cout<<x;
return 0;
}
以上,如果有什么讲的不清楚的欢迎留言私信交流~