中石油补题

2021-5-15

问题 L: 排队

思路:

构造“循环节”

#include
using namespace std;
vectorv;
int n;
int ans(vector v){
    vectorve(v);
    sort(ve.begin(),ve.end());
    mapma;
    int n=ve.size(),m=0;
    for(int i=0;if(n,false);
    for(int i=0;i>n;
    int x;
    for(int i=0;i>x;
        v.push_back(x);
    }
    cout<

延申——只交换相邻两元素的最小交换数(逆序对数

#include
using namespace std;
typedef long long ll;
const int N=100010;
int n;
int q[N],tmp[N];
ll merge_sort(int l,int r){
    if(l>=r) return 0;
    int mid=l+r>>1;
    ll sum=merge_sort(l,mid)+merge_sort(mid+1,r);
    int num=0,i=l,j=mid+1;
    while(i<=mid&&j<=r){
        if(q[i]<=q[j]) tmp[num++]=q[i++];
        else{
            tmp[num++]=q[j++];
            sum+=mid-i+1;
        }
    }
    while(i<=mid) tmp[num++]=q[i++];
    while(j<=r) tmp[num++]=q[j++];
    for(int i=l,j=0;i<=r;i++,j++)
        q[i]=tmp[j];
        return sum;
}
int main(){
    cin>>n;
    for(int i=0;i>q[i];
    cout<

2021-5-16

问题 M: 一箭多雕

题解:

对于每个位置h的雕,需要判断它前面的h+1的位置是否有一只雕,如果有,则说明h+1位置的雕可以和当前位置的雕在一支箭上,我们设置每次当前位置的雕数量++,即mp[val]++;,对于在同一支箭上的h+1的雕的数量--,即mp[val+1]--;

#include 
 
using namespace std;
unordered_mapmp;
int n, val, cnt;
 
signed main (){
//    freopen("in", "r", stdin);
    scanf("%d", &n);
    for (int i = 0;i < n; i++) {
        scanf("%d", &val);
        if (!i) mp[val]++;
        else {
            if (mp[val + 1]) mp[val + 1] -= 1;
            mp[val] += 1;
        }
    }
    for (auto x : mp) cnt += x.second;
    cout << cnt;
    return 0;
}

注意:

由于本题数据范围很大,n<=1e6

我们采用unordered_map存储

map对应的数据结构是红黑树。红黑树是一种近似于平衡的二叉查找树,里面的数据是有序的。在红黑树上做查找、插入、删除操作的时间复杂度为O(logN)。——有序

unordered_map对应哈希表,哈希表的特点就是查找效率高,时间复杂度为常数级别O(1), 而额外空间复杂度则要高出许多。所以对于需要高效率查询的情况,使用unordered_map容器,但是unordered_map对于迭代器遍历效率并不高。而如果对内存大小比较敏感或者数据存储要求有序的话,则可以用map容器。——无序

问题 L: 鸭子唱歌

#include 
#define int long long
using namespace std;
 
signed main()
{
    //freopen("in","r",stdin);
    string s ;
    cin >> s ;
    int q = 0 , qu = 0 , qua = 0 , quac = 0;
    int cnt = 0 ; int flag = 0 ;
    int Ans = INT_MAX;
    for(int i = 0 ; i < s.length() ; i++){
        if(s[i]=='q'){
            if(cnt)cnt--;
            q++;
        }else if(s[i]=='u'){
            if(q){q--,qu++;}
            else flag = 1;
        }else if(s[i]=='a'){
            if(qu)qua++,qu--;
            else flag = 1;
        }else if(s[i]=='c'){
            if(qua)quac++,qua--;
            else flag = 1;
        }else if(s[i]=='k'){
            if(quac)quac--,cnt++;
            else flag = 1;
        }
        if(quac==0&&qua==0&&qu==0&&q==0)Ans = min(Ans,cnt),cnt = 0;
    }
    if(q||qu||qua||quac)flag = 1;
    if(flag){ puts("-1");return 0;}
    printf("%d\n",Ans);
    return 0;
}

问题 E: Memory Overflow

双指针做法——加强数据后暴力不能做的情况

 

#include 
 
using namespace std;
int t, n, k, st[26];
 
signed main() {
    string str;
    scanf("%d", &t);
    for (int T = 1;T <= t; T++) {
        cin >> n >> k >> str;
        for (int i = 0; i < 26; i++) st[i] = 0;
        int l = 0, r = -1, cnt = 0;
        while (r != str.size()-1) {
            int x = str[++r] - 'A';
            if (r - l > k) st[str[l++] - 'A']--;
            if (st[x]) cnt++;
            st[x]++;
        }
        printf("Case %d: %d\n", T, cnt);
    }
    return 0;
}

问题 K: 立方

字符串模拟

#include 
 
using namespace std;
 
string mul(string s1, string s2) {
    string str = "";
    vector a(110);
    for (int i = 0; i < s1.size(); i++) {
        for (int j = 0; j < s2.size(); j++) {
            a[j + i + 1] += ((s1[s1.size() - i - 1] - '0') * (s2[s2.size() - j - 1] - '0'));
        }
    }
    for (int i = 1; i < 100; i++) a[i + 1] += a[i] / 10, a[i] %= 10;
    bool f = true;
    for (int i = 100; i >= 1; i--) {
        if (f && a[i] == 0) continue;
        f = false;
        str += to_string(a[i]);
    }
    if (f == true) str += '0';
    return str;
}
 
int cmp(string s1, string s2) { //-1小于,1大于,0等于
    if (s1 == s2) return 0;
    if (s1.size() < s2.size()) return -1;
    if (s2.size() < s1.size()) return 1;
    for (int i = 0; i < s1.size(); i++) {
        if (s1[i] > s2[i]) return 1;
        if (s1[i] < s2[i]) return -1;
    }
}
 
int main() {
    string n;
    cin >> n;
    long long l = 1, r = 10000000000;
    while (l < r) {
        long long mid = (l + r + 1) / 2;
        string mid3 = mul(mul(to_string(mid), to_string(mid)), to_string(mid));
        if (cmp(mid3, n) <= 0) l = mid;
        else r = mid - 1;
    }
    cout << r;
    return 0;
}

 

你可能感兴趣的:(题解)