acwing----春季每日一题2022篇(一)

你知道你的ABC吗(推理)

题目链接

解题思路:
由于题面已经给出了A,B,C的大小关系。那么对于这几个数,我们知道A肯定是最小的,A+B+C是最大的,对于B,C的关系,我们假设B与A之间有一个数x,那么这个x要满足严格小于B,但是在剩余的数中我们是找不到满足条件的,因此,可以推出B是第二小的,那么我们由A + B + C 的值就可以得到C的值。

代码:

#include<iostream>
#include<algorithm>
using namespace std;
const int N = 10;
int a[N];
int n = 7;

int main(){
    for(int i = 0 ; i < n ; ++i)cin>>a[i];
    sort(a,a+n);
    for(int i = 0 ; i < 2 ; ++i)cout<<a[i]<<" ";
    cout<<a[n-1] - a[0] - a[1]<<endl; // 发现也不用找,应为C一定存在,那么直接用A + B + C 的值 减去A 和B的值即可

    return 0;
}

放养但没有完全放养(贪心)

题目链接

解题思路:
这就是一个按位匹配,就是他听到的字母一定是有序(按照牛文)的,如果不是,那么就是新唱了一遍。
那么就是一直匹配就行了。

对于做法,我们库将听到的串,每匹配到一个就删去。那么当字符串长度为0的时候就匹配完全了。

代码:

#include<iostream>
#include<algorithm>
#include<string>
#include<cstring>
using namespace std;
const int N = 1010;

string str , s;

int main(){
    cin>>str>>s;

    int cnt = 0;
    while(1){
        cnt++;
        int n  = str.size();
        for(int i = 0 ; i < n ; ++i )
            if(str[i] == s[0])s.erase(s.begin());
        if(s.size() == 0) break;
    }
    cout<<cnt<<endl;

    return 0;
}

牛年(模拟)

题目链接

解题思路:
pre 表明这个人在前边也就距离Bessie 更远 , next 则是更近。我们对于每一个人存的都是距离Bessie 的距离。

  1. 如何存储值,对于每个人对应的值和生肖我们可以用map来存。
  2. 生肖刚开始的值,可以用map然后手动初始化,或者利用循环。
  3. 对于pre我们有两种对于关系,一个是我的生肖就在你前边,那么我就不用再跨越一个年份去找了。同理next ,如果已经在后边了也是。

代码:

#include<iostream>
#include<algorithm>
#include<string>
#include<cmath>
#include<map>
using namespace std;
const int N = 1100000 , INF = 0x3f3f3f3f;

map<string,int>st, ans; // ans 是 答案,也就是距离 ,st 是生肖的位置
map<string,string>bk; //记录人对应的生肖

int n ;
string str ,a ,b , op ,anl ,bnl;
string ss[14] = {"","Ox", "Tiger", "Rabbit", "Dragon", "Snake", "Horse", "Goat", "Monkey", "Rooster", "Dog", "Pig", "Rat"} ;

void init(){
    for(int i = 1 ; i <= 12 ; ++i)
        st[ss[i]] = i;
}

int main(){
    init();
    cin>>n;
    ans["Bessie"] = 0 , bk["Bessie"] = "Ox";
    while(n--){
        for(int j = 1 ; j <= 8 ; ++j){
            cin>>str;
            if(j == 1) a = str; if(j == 8) b = str;
            if(j == 4) op = str; if(j == 5) anl = str;
        }
        bk[a] = anl , bnl = bk[b];
        if(op == "next")
            {
                if(st[anl] > st[bnl]) ans[a] = ans[b] - (st[anl] - st[bnl]);
                else
                    ans[a] = ans[b] - ( 12 - st[bnl] + st[anl]); 
            }
        else{ // pre
            if(st[anl] < st[bnl]) ans[a] = ans[b] + (st[bnl] - st[anl]);
            else
                ans[a] = ans[b] + (  st[bnl] + 12 -  st[anl] ); 
        }
    }
    cout<<abs(ans["Elsie"])<<endl;
    return 0;
}

牛的学术圈 I(前缀和 + 技巧)

题目链接

题目大意
题目是要求一个最大的h,这个h满足在序列中的值大于等于h的个数至少有h个。同时由L个引用的机会。

解题思路
我们先暂时不管L个引用。对于前一个问题,我们可以对每一个数值用一个数组存下出现的个数。之后对这个数组求前缀和,那么我们就可以0(1)的复杂度,求出序列中值在[L,R]区间内的个数为s[R] - s[L-1].这样我们就解决了第一个问题。对于第二个问题,如果不限制对同一篇论文的引用次数的话,这题就复杂得多了。但是由于有了限制,那么对于h来说,哪些能通过后面这个引用满足条件呢,那就是与其差1的值的个数.如果num 小于 h,我们就看min(L,c[h-1]) >= h - num就可以了

  • 为什么加min呢,是因为我们要求的需要的个数是,值为h-1个个数中我们能用L次引用提高上来的部分。

代码:

#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
const int N = 1e5 + 10;

int n , m;
int s[N], a[N] , c[N];


int main(){
    cin>>n>>m;
    for(int i = 1; i <= n ; ++i){
        cin>>a[i];
        c[a[i]]++;
    }
    for(int i = 1 ; i < N ;  ++i)s[i] = s[i-1] + c[i];
    
    int h ;
    for( h = 1;  h  ; ++h){
        int num = s[N-1] - s[h-1];
        if(num >= h)continue;
        if(min(m,c[h-1] ) >= h - num)continue;
        break;
    }
    cout<<h-1<<endl;
    
    return 0;
}

奶牛体操(思维 + 图论)

题目链接

解题思路

在这里我们可以抽象,将排名之间的关系看成一条边。即每一次排名中,如果i在j前边,那么就建立一条i指向j的边。那么在所有关系都建立完之后,我们遍历所有的点对,如果i到j有边,但j到i没有边,那么就说明这么多次排名中j都没有在i前边,那么次数加1。

代码:

#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;

const int N = 110;
int in[N] ,a[N];
int n , m;
bool st[N][N];

int main(){
    cin>>m>>n;
    while(m--){
        for(int i = 1 ; i <= n ; ++i)
            cin>>a[i];
        // 建立关系
        for(int i = 1 ; i <= n ; ++i)
            for(int j = i + 1 ; j <= n ; ++j)
                st[a[i]][a[j]] = 1;
    }
    int ans = 0;
    for(int i = 1 ; i <= n ; ++i)
        for(int j = 1 ; j <= n ; ++j){
            if(st[i][j] && !st[j][i]) // 由于在建边的时候没有建立自己指向自己的所有不用特判
                ans++ ; //如果i 指向j ,但j没有指向i,说明在这么多次排名中i都在j前边
        }
    cout<<ans<<endl;
    return 0;
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

落春只在无意间

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值