1. 程式人生 > >Codeforce Round #424

Codeforce Round #424

stack 排序 結果 距離 一次 最終 sort print min

A 略 B 略

C:

先對Ai數列預處理前綴和 然後把Bi的每個都加一次 最終得到的結果為ans[sum]++; 最後如果有一個ans[sum]>=k即滿足所有K個條件就輸出(註意!!前綴和要進行unique操作!!!因為可能會有+1 -1 +1這種出現

技術分享
#include <bits/stdc++.h>
#include <cstring>
#include <iostream>
#include <algorithm>
#define foror(i,a,b) for(i=a;i<b;i++)
#define foror2(i,a,b) for(i=a;i>b;i--)
#define
EPS 1.0e-6 #define PI acos(-1.0) #define INF 3000000000 #define MOD 1000000009 #define mem(a,b) memset((a),b,sizeof(a)) #define TS printf("!!!\n") #define lson o<<1, l, m #define rson o<<1|1, m+1, r //using ll = long long; //using ull= unsigned long long; //std::ios::sync_with_stdio(false); using namespace std;
//priority_queue<int,vector<int>,greater<int>> que; typedef long long ll; map<int,int> mp; stack<int> s; int main() { //freopen("in.txt", "r", stdin); //freopen("out.txt", "w", stdout); int n,k; int ans; cin >> n >> k; int a[n+10],b[k+10]; for(int i=1;i<=n;i++) { scanf(
"%d",&a[i]); a[i]=a[i-1]+a[i]; } for(int i=1;i<=k;i++) { scanf("%d",&b[i]); } sort(a+1,a+1+n); int lenth=unique(a+1,a+1+n)-(a+1); for(int i=1;i<=k;i++) { for(int j=1;j<=lenth;j++) { s.push(b[i]]+a[j]); mp[b[i]]+a[j]]++; } } for(int i=0;i<s.size();i++) { if(mp[s[i]>=k) { ans++; mp[s[i]]=0; } } cout<<ans<<endl; return 0; }
View Code

D:

二分或者DP

二分:由於要盡可能使每個人拿到距離自己最近的鑰匙,我們先把所有人根據位置排序,把所有鑰匙根據位置排序,然後二分答案,判斷某一個值是否滿足條件,具體判斷過程見代碼,每次盡量取左邊的鑰匙。

技術分享
#include <cstdio>
#include <map>
#include <iostream>
#include <queue>
#include <cstring>
#include <algorithm>
using namespace std;
#define mst(a,b) memset((a),(b),sizeof(a))
#define rush() int T;scanf("%d",&T);while(T--)

typedef long long ll;
const int maxn= 2005;
const int mod = 20090717;
const int INF = 0x3f3f3f3f;
const double eps = 1e-6;

int n,k,p;
ll a[maxn];
ll b[maxn];
bool vis[maxn];

bool judge(ll limit)
{
    int num=0;
    mst(vis,0);
    for(int i=0;i<k;i++)
    for(int j=0;j<n;j++)
    {
        if(vis[j]) continue;
        if(abs(b[i]-a[j])+abs(b[i]-p)<=limit)
        {
            vis[j]=true;
            num++;
            break;
        }
    }
    return num==n;
}

int main()
{
    scanf("%d%d%d",&n,&k,&p);
    for(int i=0;i<n;i++)
    {
        scanf("%I64d",&a[i]);
    }
    for(int i=0;i<k;i++)
    {
        scanf("%I64d",&b[i]);
    }
    sort(a,a+n);
    sort(b,b+k);
    ll l=0,r=2e9+5;
    ll ans;
    while(l<=r)
    {
        ll m=(l+r)/2;
        if(judge(m))
        {
            r=m-1;
            ans=m;
        }
        else l=m+1;
    }
    printf("%I64d\n",ans);
    return 0;
}
View Code

DP:

用dp[i][j]表示前i個人在前j把鑰匙中都拿到了鑰匙並到達公司的最短時間。(所有人最短時間裏的最大值)

可以寫出狀態轉移方程:dp[i][j]=min(dp[i][j-1],max(dp[i-1][j-1]+abs(pos[j]-p))) 最終結果便是dp[n][k].

技術分享
#include <cstdio>
#include <map>
#include <iostream>
#include <queue>
#include <cstring>
#include <algorithm>
using namespace std;
#define mst(a,b) memset((a),(b),sizeof(a))
#define rush() int T;scanf("%I64d",&T);while(T--)

typedef long long ll;
const int maxn= 2005;
const int mod = 20090717;
const ll INF = 1e15;
const double eps = 1e-6;

int n,k;
ll p;
ll a[maxn];
ll b[maxn];
ll dp[maxn][maxn];


int main()
{
    scanf("%d%d%I64d",&n,&k,&p);
    for(int i=1;i<=n;i++)
    {
        scanf("%I64d",&a[i]);
    }
    for(int i=1;i<=k;i++)
    {
        scanf("%I64d",&b[i]);
    }
    sort(a+1,a+1+n);
    sort(b+1,b+1+k);
    mst(dp,0);
    for(int i=1;i<=n;i++)
    for(int j=i;j<=k;j++)
    {
        if(i==j)
            dp[i][j]=max(dp[i-1][j-1],abs(a[i]-b[j])+abs(b[j]-p));   //由j>=i,故i==j時特判
        else dp[i][j]=min(dp[i][j-1],max(dp[i-1][j-1],abs(a[i]-b[j])+abs(b[j]-p)));
    }
    printf("%I64d\n",dp[n][k]);
    return 0;
}
View Code

Codeforce Round #424