首页 > 代码库 > Codeforces_714

Codeforces_714

A.相遇时间段l = max(l1,l2),r = min(r1,r2),再判断k是否在里面。

技术分享
#include <iostream>
using namespace std;

long long l1,l2,r1,r2,k;
 
int main()
{
       cin >> l1 >> r1 >> l2 >> r2 >> k;
       long long l = max(l1,l2),r = min(r1,r2);
       if(l > r)    cout << 0 << endl;
       else
       {
           long long t = r-l+1;
           if(l <= k && k <= r)    t--;
           cout << t << endl;
    }
    return 0;
}
View Code

B.判断出现的数的个数,1或2个直接YES,3个以上直接NO,3个判断是否等差。

技术分享
#include<bits/stdc++.h>
using namespace std;

int n,a[100005];
map<int,int> mp;

int main()
{
    ios::sync_with_stdio(false);
    cin >> n;
    int cnt = 0;
    for(int i = 1;i <= n;i++)
    {
        int x;
        cin >> x;
        if(!mp.count(x))
        {
            cnt++;
            mp[x] = 1;
            a[cnt] = x;
        }
    }
    if(cnt == 1 || cnt == 2)    cout << "YES" << endl;
    else if(cnt >= 4)   cout << "NO" << endl;
    else
    {
        sort(a+1,a+4);
        if(a[1]+a[3] == 2*a[2]) cout << "YES" << endl;
        else    cout << "NO" << endl;
    }
    return 0;
}
View Code

C.把每一个数都转换成18位的pattern串,放进map处理。

技术分享
#include<bits/stdc++.h>
using namespace std;

int n;
map<string,int> mp;

int main()
{
    ios::sync_with_stdio(false);
    cin >> n;
    while(n--)
    {
        string s1,s2,s = "";
        cin >> s1 >> s2;
        for(int i = s2.length()-1;i >= 0;i--)
        {
            if((s2[i]-0)%2)   s = "1"+s;
            else    s = "0"+s;
        }
        while(s.length() < 18)  s = "0"+s;
        if(s1 == "+")   mp[s]++;
        else if(s1 == "-")  mp[s]--;
        else    cout << mp[s] << endl;
    }
    return 0;
}
View Code

D.先把图分成左右或上下两块,然后二分每一块中矩形的四条边。

技术分享
#include<bits/stdc++.h>
using namespace std;

int n;
struct xx
{
    long long x1,x2,y1,y2;
    void print()
    {
        cout << x1 << " " << y1 << " " << x2 << " " << y2 << " ";
    }
};

int query(int x1,int y1,int x2,int y2)
{
    if(x1 > x2)swap(x1,x2);
    if(y1 > y2)swap(y1,y2);
    cout<<"? "<<x1<<" "<<y1<<" "<<x2<<" "<<y2<<endl;
    int ans;
    cin>>ans;
    return ans;
}

xx f(int x1,int y1,int x2,int y2)
{
    xx ans;
    long long l = x1,r = x2;
    while(l < r)
    {
        int mid = (l+r)/2;
        if(query(x1,y1,mid,y2) < 1) l = mid+1;
        else    r = mid;
    }
    ans.x2 = l;
    l = x1,r = x2;
    while(l < r)
    {
        int mid = (l+r+1)/2;
        if(query(mid,y1,x2,y2) < 1) r = mid-1;
        else    l = mid;
    }
    ans.x1 = l;
    l = y1,r = y2;
    while(l < r)
    {
        int mid = (l+r)/2;
        if(query(x1,y1,x2,mid) < 1) l = mid+1;
        else    r = mid;
    }
    ans.y2 = l;
    l = y1,r = y2;
    while(l < r)
    {
        int mid = (l+r+1)/2;
        if(query(x1,mid,x2,y2) < 1) r = mid-1;
        else    l = mid;
    }
    ans.y1 = l;
    return ans;
}
int main()
{
    cin >> n;
    long long x1,y1,x2,y2,x3,y3,x4,y4;
    long long l = 1,r = n;
    while(l < r)
    {
        long long mid = (l+r)/2;
        if(query(1,1,mid,n) < 1)    l = mid+1;
        else    r = mid;
    }
    long long t = l;
    if(query(1,1,t,n) == 1 && query(t+1,1,n,n) == 1)
    {
        xx a = f(1,1,t,n),b = f(t+1,1,n,n);
        cout << "! ";
        a.print();
        b.print();
        cout << endl;
        return 0;
    }
    l = 1,r = n;
    while(l < r)
    {
        long long mid = (l+r)/2;
        if(query(1,1,n,mid) < 1)    l = mid+1;
        else    r = mid;
    }
    t = l;
    xx a = f(1,1,n,t),b = f(1,t+1,n,n);
    cout << "! ";
    a.print();
    b.print();
    cout << endl;
    return 0;
}
View Code

E.如果是非严格单调递增该如何做,我们会发现每次调整,都是调整某个数字为原先数列中存在的数字,最后才是最优的,所以,我们设DP[i][j]表示前i个数字,最后一个数为原先数列排序后第j大的数字的最小代价,然后令a[i]=a[i]-i,把严格单调递增就转化为非严格单调递增。

技术分享
#include<bits/stdc++.h>
using namespace std;

int n;
long long a[3005],b[3005],dp[3005][3005];

int main()
{
    cin >> n;
    for(int i = 1;i <= n;i++)
    {
        cin >> a[i];
        a[i] -= i;
        b[i] = a[i];
    }
    sort(b+1,b+1+n);
    for(int i = 1;i <= n;i++)
    {
        long long minn = dp[i-1][1];
        for(int j = 1;j <= n;j++)
        {
            minn = min(minn,dp[i-1][j]);
            dp[i][j] = abs(a[i]-b[j])+minn;
        }
    }
    long long ans = dp[n][1];
    for(int i = 1;i <= n;i++)   ans = min(ans,dp[n][i]);
    cout << ans << endl;
    return 0;
}
View Code

还有优先队列优化的。

技术分享
#include<bits/stdc++.h>
using namespace std;

int n;
priority_queue<long long> q;

int main()
{
    cin >> n;
    long long ans = 0;
    for(int i = 1;i <= n;i++)
    {
        long long x;
        cin >> x;
        x -= i;
        q.push(x);
        if(q.top() > x)
        {
            ans += q.top()-x;
            q.pop();
            q.push(x);
        }
    }
    cout << ans << endl;
    return 0;
}
View Code

 

Codeforces_714