好题456

空调

#include <iostream>
#include <cstring>
#include <algorithm>

using namespace std;

const int N = 100010;

int n;
int a[N];

int main()
{
    scanf("%d", &n);
    for (int i = 1; i <= n; i ++ ) scanf("%d", &a[i]);
    for (int i = 1; i <= n; i ++ )
    {
        int b;
        scanf("%d", &b);
        a[i] -= b;
    }

    for (int i = n; i; i -- ) a[i] -= a[i - 1]; //注意这里求差分
    //要倒着求 因为你这种求差分是用原数组记录它的差分所以要倒着

    int pos = 0, neg = 0;
    for (int i = 1; i <= n; i ++ )
        if (a[i] > 0) pos += a[i];
        else neg -= a[i];

    printf("%d\n", max(pos, neg));
    return 0;
}


谎牛计数

#include<iostream>
#include<algorithm>
#include<cstring>
#define x first
#define y second
using namespace std;
const int N=1010;
pair<int,char>a[N];
int s[N],r[N]; // s[i]=k 表示第i头牛(包含i)前面有k个说小于等于的
// r[i]=k 表示第i头牛(baohani)后面有k个说大于等于的
int main(){
    int n;
    cin >> n;
    for(int i=1;i<=n;i++){
        cin >> a[i].y >> a[i].x ;
    }
    sort(a+1,a+n+1);
    for(int i=1;i<=n;i++){
        s[i]=s[i-1];
        if(a[i].y=='L') s[i]++;
    }
    for(int i=n;i;i--){
        r[i]=r[i+1];
        if(a[i].y=='G') r[i]++;
    }
    int res=n;
    for(int i=1;i<=n;i++){
        res=min(res,s[i]+r[i]-1);
    }
    cout << res << endl;
    return 0;
}

巧克力

//贪心 优先队列自定义排序
#include<iostream>
#include<cstring>
#include<algorithm>
#include<queue>
#include<map>
using namespace std;
const int N=1e5+10;
struct Node{
    int a,b,c,id;
}goods[N];
map<int,int>mp;
int n,x;
bool cmp1(Node a,Node b){
    return a.b>b.b;   // 日期按从大到小排序
}

struct cmp2{
	bool operator()(const Node &p,const Node &q){
		return p.a>q.a;//从小到大排序 
	}
};
int main(){
    cin >> x >> n;
    for(int i=1;i<=n;i++){
        cin >> goods[i].a >> goods[i].b >> goods[i].c ; // 单价 日期 数量
        goods[i].id=i;
    }
    sort(goods+1,goods+1+n,cmp1);
    priority_queue<Node,vector<Node>,cmp2>q;
    int j=1;
    int res=0;
    for(int i=x;i>=1;i--){
        while(goods[j].b>=i&&j<=n){
            q.push(goods[j]);
            j++;
        }
        if(!q.size())//如果中间某一天没有可以选择的巧克力,那就不存在一个合法的方案 
		{
			cout<<"-1"<<endl;
			return 0; 
		}

        auto tmp=q.top();
        res+=tmp.a;
        mp[tmp.id]++;
        if(mp[tmp.id]==tmp.c){
            q.pop();
        }
    }
    cout << res;
    return 0;
}

连接奶牛

//每一种走法都对应一种全排列,比如1342 说明先走到1再走到3 4 2 
//我们只需要判断这个全排列是否合法即可  时间复杂度(n*n!)
//这个全排列合法需要满足:
//1.可以从起始点(0,0)走到第一个点,可以从最后一点走到起始点
//2.每两个相邻的点必须在同一行或者同一列
//3.每三个相邻的点必定要发生变向 比如a通过方向x到b,b通过方向y到c,则x!=y,否则
//说明没有发生变向不符合题意
#include<iostream>
#include<cstring>
#include<algorithm>
#define x first
#define y second
using namespace std;
const int N=12;
pair<int,int>p[N];
int q[N];
int n;
int get(pair<int,int>a,pair<int,int>b){
    if(a.x!=b.x&&a.y!=b.y) return -1; // 既不在同一行又不在同一列
    if(a.x==b.x){  // 在同一列
        if(a.y<b.y) return 0;
        else return 2;
    }
    if(a.y==b.y){ // 在同一行
        if(a.x<b.x) return 1;
        else return 3;
    }
    return -1;
}
int main(){
    cin >> n;
    int res=0;
    for(int i=1;i<=n;i++) cin >> p[i].x >> p[i].y;
    for (int i = 1; i <= n; i ++ ) q[i] = i;  // 全排列不要忘了初始化
    do{
        int tmp,last,flag=0;
        for(int i=1;i<=n+1;i++){
            tmp=get(p[q[i]],p[q[i-1]]);
            if(tmp==-1||tmp==last) {
                last=-1;
                break;
                }
            last=tmp;
        }
        if(last!=-1) res++;
    }while(next_permutation(q+1,q+n+1));
    cout << res << endl;
    return 0;
}

错题

//合法的括号序列:最简单的定义为字符串所包含的 ( 和 ) 数量必须相同,
//并且对于字符串的任意前缀,所包含的 ( 的数目都不少于 ) 的数目。
//上面是非常重要的定理
//对于本题如果某个前缀中左括号数量小于右括号数量了,说明右括号多了,则改变
//该前缀中的任意一个右括号都是一种合法的做法,反之如果某个后缀中左括号数量大于右括号数量了,同理即可
#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
int l,r;
int main(){
    string s;
    cin >> s;
    for(auto c:s){
        if(c=='('){
            l++;
        }
        else r++;
    }
    int a=0,b=0;
        int cnt=0;
    if(l==r){
        cout << 0;
    }
    else if(r>l){   // 说明右括号太多了 需要改变右括号
        for(auto c:s){
            if(c=='(') a++;
            else {
                b++;
            }
            if(a<b){
                cout << b;
                break;
            }
        }
    }
    else {
        reverse(s.begin(),s.end());
       // cout << s << endl;
        for(auto c:s){
            cnt++;
            if(c=='(') a++;
            else {
                b++;
            }
            if(b<a){
                cout << a;
                break;
                }
        }
    }
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值