记录几道水题
第一题
题目链接
题目大意:给 n和m 问1-n里面m的倍数中个位数的和是多少.
某场div3的c题. n/m肯定是1-n里面m倍数的个数.那么这些数里面各位数的和怎么算呢?分析一下可以知道最多10个数后就会进入循环.因为0-9只有10个数嘛.可以手动先把每个数的循环数组算出来.当然这是最直接的做法.还有一种偷懒的算法.
因为最多10个就进入循环.那么我们直接for(1-10)遍历一遍m 1-10的倍数就可以了.具体看代码
#define LL long long
#include <algorithm>
#include <iostream>
#include <stack>
using namespace std;
const int N = 2e5+10;
int main(){
LL n,t,m;
cin >> t;
while(t--){
cin >> n >> m;
LL num = n/m;
int l = num%10;
LL ans=0;
LL tmp=0;
for(int i=1;i<=10;++i){
tmp += (i*m)%10;
if(i <= l) ans+= (i*m)%10;
}
ans += (num/10)*tmp;
cout << ans << endl;
}
return 0;
}
第二题
题目链接
题目大意:给一个数组 可以对任意一个数操作使它除2向下取整.问最少操作几次可以让数组里面有k个相同的数字.
同场的D题.类似桶排的思想.贪心的先排序.从小到大考虑.记录这个数操作到0的途中经过的那些数的操作数.什么时候>=k了,和ans比较一下.取最小的那一个.
代码
#define LL long long
#include <algorithm>
#include <iostream>
#include <stack>
using namespace std;
const int N = 2e5+10;
int a[N];
int num[N];
LL cnt[N];
bool vis[N];
int main(){
int n,k,x;
cin >> n >> k;
LL ans = 1e17+10;
for(int i=1;i<=n;++i){
cin >> a[i];
num[a[i]] ++;
if(num[a[i]] >= k){
vis[a[i]] = 1;
ans = 0;
}
}
sort(a+1,a+1+n);
for(int i=1;i<=n;++i){
int tmp = 0;
while(a[i] > 0){
tmp++;
if(!vis[a[i]/2]){
num[a[i]/2]++;
cnt[a[i]/2] += tmp;
if(num[a[i]/2] >= k){
// cout << a[i]/2 << " " << cnt[a[i]/2] << endl;
vis[a[i]/2] = 1;
ans = min(ans,cnt[a[i]/2]);
}
}
a[i] >>= 1;
}
}
cout << ans << endl;
return 0;
}
第三题
题目链接
题目大意:给1-n的一组排列 问是否是一个1-n的环.
某场div3的A题.大水题.暴力的做法随便都能过.考虑稍微巧妙一点的做法.因为只要是一个1-n环就可以.这个环的特点就是 后面的数-前面的数>1的值只有一个.
上代码.
#define LL long long
#include <algorithm>
#include <iostream>
#include <stack>
using namespace std;
const int N = 2e5+10;
int a[N];
int main(){
int t;
cin >> t;
while(t--){
int n;
cin >> n;
int num = 0;
cin >> a[1];
for(int i=2;i<=n;++i){
cin >> a[i];
if( abs(a[i]-a[i-1]) > 1) num++;
}
if( abs(a[n]-a[1]) > 1) num++;
if(num >= 2) cout << "NO\n";
else cout << "YES\n";
}
return 0;
}