A - From Hero to Zero
题意:给出n和k,有两种操作,一是n-1 ,二是当n可以整除于k时整除k,问最少的操作次数使n变成0。
题解:直接n一直除于k然后加上中间的差值就行了。
#include <cstdio>
#include <iostream>
#include <algorithm>
using namespace std ;
typedef long long ll ;
int main(){
int t ;
cin >> t ;
while(t --){
ll n , k ;
cin >> n >> k ;
ll cnt = 0 ;
while(n){
ll m = n ;
n /= k , ++ cnt ;
cnt += m-n*k ;
}
cout << cnt-1 << endl ;
}
return 0 ;
}
B - Catch Overflow!
题意:给出n个命令,有三种命令“for” “add” “end” , for后面紧跟着数字x,表示循环x次,多个for为嵌套,end为结束最近的一个for,add是计数当前的执行次数。
题解:模拟,栈顶存放当前的循环次数,end就弹出,add就加上栈顶元素,但是要注意细节,首先是long long 有可能也会爆所以压入栈之前取INF和栈顶的最小值即可,然后就是INF了,它是不超过!!!就是可以等于,我居然没注意到,所以INF设置为232 - 1 , 其实应该设置为232即可,然后一直卡在第7个测试(卡了一个多小时。。。。。。。)
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <stack>
#include <cstring>
#include <string>
using namespace std ;
typedef long long ll ;
stack<ll> s ;
const ll INF = 4294967296 ;
int main(){
int t ;
cin >> t ;
ll f = 1 , cnt = 0 , n = 1 ;
string comm ;
s.push((ll)1) ;
while(t --){
cin >> comm ;
if (comm == "for"){
cin >> n ;
s.push(min(INF,s.top()*n)) ;
}
else if (comm == "add"){
cnt = min(cnt+s.top(),INF) ;
}
else if (comm == "end"){
s.pop() ;
}
}
if (cnt == INF) cout << "OVERFLOW!!!" << endl ;
else cout << cnt << endl ;
return 0 ;
}
C. Electrification
题意:在一维数轴上给出n个点的坐标和k,然后要求找出一个新点,要求新点的到给定点的距离第k+1大值尽量小。
题解:(偷偷抄大佬题解→)来源
检查靠外的n-k对数:a[i]和a[i+k],找出靠得最近的一对并记录中点即可。
#include <cstdio>
#define rep1(i,a,b) for(int i=a;i<=b;++i)
const int N = 2e5 + 5 ;
int a[N] ;
int main(){
int n , k , t ;
scanf("%d",&t) ;
while(t --){
scanf ("%d%d",&n,&k) ;
int dmin = 0x3f3f3f3f , ans = 0 ;
rep1(i,1,n) scanf("%d",&a[i]) ;
rep1(i,1,n-k)
if (dmin > (a[i+k]-a[i]+1)/2){
dmin = (a[i+k]-a[i]+1)/2 ;
ans = (a[i+k]+a[i])/2 ;
}
printf ("%d\n",ans) ;
}
return 0 ;
}
D - Array Splitting
题意:给出长度为n的数组,要求分成k个数组,问所有的数组乘上相应的子序列的编号最大为多少。
题解:先求后缀和然后排序再翻转,但是要注意sort的时候不要包含a[1],因为序列每个元素都至少被算过一次。(大佬题解牛逼,是我太菜了),这应该是第一次遇到后缀和的题吧。
#include <cstdio>
#include <algorithm>
using namespace std ;
const int N = 3e5 + 10 ;
typedef long long ll ;
ll a[N] ;
int main(){
int n , k ;
scanf ("%d%d",&n,&k) ;
for(int i = 1 ; i <= n ; ++ i) scanf ("%lld",&a[i]) ;
for (int i = n ; i >= 1 ; -- i)
a[i] += a[i+1] ; //后缀和
ll ans = 0 ;
sort(a+2,a+n+1) ;
reverse(a+2,a+n+1) ;
for (int i = 1 ; i <= k ; ++ i)
ans += a[i] ;
printf ("%lld\n",ans) ;
return 0 ;
}