A - Three Friends
题目链接
思路:3个数可以选择+1或者-1或者不变,最终要求操作一次后3者之间差的绝对值最小,2种思想:
1、数学角度考虑2大1小,2小1大等情况进行考虑。
2、最简单的思路:3重循环6次遍历所有情况,拿最小值。
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const long long inf=233333333333333; //要开足够大0x3f3f3f3f不够大
int main(){
ll q, a, b, c;
cin >> q;
while(q--){
ll ans=inf;
scanf("%lld%lld%lld",&a,&b,&c);
for(ll i=a-1; i<=a+1; i++){
for(ll j=b-1; j<=b+1; j++){
for(ll k=c-1; k<=c+1; k++){
if(ans>fabs(i-j)+fabs(j-k)+fabs(i-k)){
ans=abs(i-j)+abs(j-k)+abs(i-k);
}
}
}
}
printf("%lld\n",ans);
}
return 0;
}
B - Polycarp Training
题目链接
题目大意:一个acmer第k天能刷k题,而他有一系列的比赛,如果某天剩余比赛没有一个题数大于当天他所能刷的题数,那么他停止刷题,问最大刷题天数
思路:先对输入的比赛题数进行排序,然后我们再遍历,因为k是不断刷新,只要我们找不到大于当前的k就行了(原因是从小到大排好序了,考虑过的不用再考虑了)
#include <bits/stdc++.h>
using namespace std;
const int maxn = 2e5+10;
int a[maxn];
int main()
{
int n;
scanf("%d",&n);
for(int i=0;i<n;i++)
scanf("%d",&a[i]);
sort(a,a+n);
int sum=0,k=1;
for(int i=0;i<n;i++)
{
if(a[i]>=k)
{
sum++;
k++;
}
}
printf("%d\n",sum);
return 0;
}
C - Yet Another Broken Keyboard
题目链接
题目大意:找给定字母在字符串中的连续子串数。
思路:我们可以直接遍历一遍找连续,但一定要注意直接连到尾的那种要单独处理一下(这是一种思想,可以用于很多题的)。
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
bool vis[26];
int main(){
int n, k;
string s;
char ch;
cin >> n >> k;
cin >> s;
for(int i=0; i<k; i++){
cin >> ch;
vis[ch-'a']=true;
}
ll sum=0, ans=0;
for(int i=0; i<s.size(); i++){
if(vis[s[i]-'a']) ans++;
else{
sum+=((1+ans)*ans/2);
ans=0;
}
if(vis[s[i]-'a']&&i==n-1){
sum+=((1+ans)*ans/2);
ans=0;
}
}
cout << sum;
return 0;
}
D - Snow Walking Robot
题目链接
题目大意:这题主要读懂,读懂就会。意思就是不让机器人走重复的路,那就是说机器人绕一个圈回到原点。
思路:我们就要取L和R中最小和U和D中最小作为最终要走的步数,如果其中仅含L和R或者U和D,那就输出2个就好了
#include <bits/stdc++.h>
using namespace std;
int l, r, u, d;
int q;
string s;
int main(){
cin >> q;
while(q--){
cin >> s;
l=0, r=0, u=0, d=0;
for(int i=0; i<s.size(); i++){
if(s[i]=='L') l++;
if(s[i]=='R') r++;
if(s[i]=='U') u++;
if(s[i]=='D') d++;
}
int m=min(l,r), n=min(u,d);
if(m>0&&n>0){
printf("%d\n",m*2+n*2);
for(int i=1; i<=m; i++) printf("L");
for(int i=1; i<=n; i++) printf("U");
for(int i=1; i<=m; i++) printf("R");
for(int i=1; i<=n; i++) printf("D");
}
else{
if(m>0) printf("2\nLR");
else if(n>0) printf("2\nUD");
else printf("0");
}
puts("");
}
return 0;
}
G - Cow and Snacks
题目链接
思路:并查集思想,不断用find函数刷新每一个食物的根节点,从而找到最小的沮丧人数。
#include <bits/stdc++.h>
using namespace std;
const int maxn = 2e5+10;
int fa[maxn];
int x, y;
int find(int u){
if(fa[u]==u) return u;
return fa[u]=find(fa[u]);
}
int main(){
int n, k;
cin >> n >> k;
int sum=0;
for(int i=1; i<=n; i++) fa[i]=i;
for(int i=1; i<=k; i++){
cin >> x >> y;
x=find(x), y=find(y);
if(x!=y) fa[x]=y;
else sum++;
}
cout << sum;
return 0;
}
F - Coffee Break
题目链接
思路:优先队列模拟,让最小的永远排在前面,同时用一个结构体,包含第几秒休息,第几天休息,本身输入时的位置
#include <bits/stdc++.h>
using namespace std;
struct node{
int x, num, pos;
};
vector <node> v;
priority_queue <int,vector<int>,greater<int> > g;
bool cmp1(node a, node b){
return a.x<b.x;
}
bool cmp2(node a, node b){
return a.pos<b.pos;
}
int n, m, d;
int a;
int main(){
scanf("%d%d%d",&n,&m,&d);
for(int i=1; i<=n; i++){
scanf("%d",&a);
v.push_back({a,0,i});
}
sort(v.begin(),v.end(),cmp1);
int day=1;
int ans=0;
g.push(v[0].x);
v[0].num=1;
for(int i=1; i<v.size(); i++){
int cnt=g.top();
if(cnt+d>=v[i].x){
day++;
v[i].num=day;
g.push(v[i].x);
}
else{
g.push(v[i].x);
v[i].num=v[ans].num;
ans++;
g.pop();
}
}
sort(v.begin(),v.end(),cmp2);
printf("%d\n%d",day,v[0].num);
for(int i=1; i<v.size(); i++){
printf(" %d",v[i].num);
}
return 0;
}