CodeChef Add or Multiply 【思维】

来源:互联网 发布:图像算法工程起薪 编辑:程序博客网 时间:2024/06/03 19:28



思路:


我们O(n*m)求出两两点间差值,然后我们枚举两点(i,j),我们使得点i和点j重合跑一遍最优匹配,然后再使得点i放在点j左边e处跑一遍最优匹配,然后再使得点i放在点j右右边e处跑一遍最优匹配即可。


这里不能用匈牙利最大匹配去跑,因为会TLE ,我们两点法去贪心去做,拿最左边的A数组中的数取匹配最左边B数组中的数即可。


Ac代码:

#include<stdio.h>#include<string.h>#include<algorithm>using namespace std;#define ll long long intll a[1500];ll b[1500];ll dist[450][450];ll temp[450];int n,m;ll e;int Slove(ll x) {    for(int i=1; i<=n; i++)  temp[i]=a[i]-x;    int ans = 0;    for(int i=1,j=1;i<=n&&j<=m;){        if(abs(temp[i]-b[j])<=e) i++,j++,ans++;        else if(temp[i]<b[j]) i++;        else j++;    }//    printf("%lld %d\n",x,ans);    return ans;}int main() {    int t;    scanf("%d",&t);    while(t--) {        scanf("%d%d%lld",&n,&m,&e);        for(int i=1; i<=n; i++)scanf("%lld",&a[i]);        sort(a+1,a+1+n);        for(int i=1; i<=m; i++)scanf("%lld",&b[i]);        sort(b+1,b+1+m);        for(int i=1; i<=n; i++) {            for(int j=1; j<=m; j++) {                dist[i][j]=(a[i]-b[j]);            }        }        int ans=0;        ans=max(Slove(0),ans);        for(int i=1; i<=n; i++) {            for(int j=1; j<=m; j++) {                ans=max(Slove(dist[i][j]-e),ans);                ans=max(Slove(dist[i][j]+e),ans);            }        }        printf("%d\n",ans);    }}








原创粉丝点击