完全数

题意

给定一个数n,求出1~n-1内所有n的因数的和m
若 n == m ,输出 Pure
若 n > m , 输出Late
若 n < m ,输出 Early

思路

直接暴力枚举1~n内所有n的因子数时间复杂度1e14,铁定是超时的
当存在一个数 ,满足 的因子时,必然有 也是n的因子,所以只需要枚举~内所有的数即可

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
inline ll read(){
    ll s = 0, w = 1; char ch = getchar();
    while (ch < 48 || ch > 57) { if (ch == '-') w = -1; ch = getchar(); }
    while (ch >= 48 && ch <= 57) s = (s << 1) + (s << 3) + (ch ^ 48), ch = getchar();
    return s * w;
}
int main(){
    ll n = read();
    ll ans = 1;//1一定是n的因子
      for(int i=2;i<=sqrt(n);i++){
          if(n%i==0) {
              if(i==n/i) ans+=i;//当i*i == n时,不需要加上n/i了
              else ans+=i+n/i;//i是n的因子时n/i也是
          }

    }
    if(ans < n) puts("Early");
    else if(ans == n) puts("Pure");
    else puts("Late");
}

移动撤销

题意

在一个无限大的空间内有5中操作 ,分别表示向左,上,下,右移动一格 表示撤回之前的一次移动,注意操作不会撤回之前的操作,当操作之前没有操作时不进行任何行动
起点为(0,0),输出最后所在位置的坐标

思路

很明显的栈操作,当本次操作是移动操作时将本次移动方向入栈,是撤回操作时判断栈是否为空,为空则不操作,否则弹出栈顶元素回退操作

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
inline ll read(){
    ll s = 0, w = 1; char ch = getchar();
    while (ch < 48 || ch > 57) { if (ch == '-') w = -1; ch = getchar(); }
    while (ch >= 48 && ch <= 57) s = (s << 1) + (s << 3) + (ch ^ 48), ch = getchar();
    return s * w;
}
stack<pair<int,int> > q;//first存x轴方向上的操作,second存y轴方向上的操作
int main(){
    int n = read();
    string s;
    cin>>s;
    int x = 0,y = 0;
    for(int i = 0 ; i < n ; ++i){
        if(s[i] =='W'){
            y++;q.push({0,-1});
        }
        else if(s[i] =='A'){
            x--;q.push({1,0});
        }
        else if(s[i] == 'S'){
            y--;q.push({0,1});
        }
        else if(s[i] == 'D'){
            x++;q.push({-1,0});
        }
        else{
            if(!q.empty()){
                x += q.top().first;
                y += q.top().second;
                q.pop();
            }
        }
    }
    cout<<x<<" "<<y<<endl;
}

石头剪刀布

思路

直接贪心即可,分别算出牛牛能赢牛妹的操作,减去对应的次数再算平局的操作就好

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;

int main(){
        int n,p1,q1, m1, p2, q2, m2;
        ll ans=0;
        cin>>n>>p1>>q1>>m1>>p2>>q2>>m2;
        int cnt1 = min(p1, q2);
        p1 -= cnt1;
        q2 -= cnt1;
        int cnt2 = min(q1, m2);
        q1 -= cnt2;
        m2 -= cnt2;
        int cnt3 = min(m1, p2);
        m1 -= cnt3;
        p2 -= cnt3;
        ans+=(cnt1+cnt2+cnt3)*2;//赢了两分
        ans += min(p1,p2) + min(q1,q2) + min(m1,m2);
        cout<<ans<<endl;
}

夹缝中求和

思路

枚举每个 找到 一个使得
为了方便查找,先对数组排序,直接用库函数lower_bound就好

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
inline ll read(){
    ll s = 0, w = 1; char ch = getchar();
    while (ch < 48 || ch > 57) { if (ch == '-') w = -1; ch = getchar(); }
    while (ch >= 48 && ch <= 57) s = (s << 1) + (s << 3) + (ch ^ 48), ch = getchar();
    return s * w;
}
vector<ll> q;
int main(){
    ll n = read(),x = read(),y = read();
    for(int i = 0 ; i < n  ;++i){
        ll tmp = read();
        if(tmp <= y) q.push_back(tmp);//当ai比y大时显然不可能存在ai+aj <= y
    }
    sort(q.begin() ,q.end());
    ll ans = 0;
    for(ll i = 0 ; i < q.size() ;++i){
        ll r = upper_bound(q.begin(),q.end(),y - q[i]) - q.begin();
        ll l = lower_bound(q.begin(),q.end(),x - q[i]) - q.begin();
        l = max(i+1,l);//找到的j一定要比i大,不然可能会有重复
        ans +=  r - l  >= 0 ? r - l : 0;//i+1可能比r要大
    }
    cout<<ans<<endl;
}