Wannafly挑战赛26

版权声明:转就转吧~~记得声明噢~~ https://blog.csdn.net/Soul_97/article/details/83042969

https://www.nowcoder.com/acm/contest/212#question

A题  

n最大是1000  直接暴力匹

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll N = 100005;
const ll INF = 0x3f3f3f3f;
const ll mod = 1e9 + 7;
vector<pair<ll,ll> > v;
int main()
{
    int n;
    cin >> n;
    ll x, y;
    for(ll i = 1;i <= n;i ++){
        cin >> x >> y;
        v.push_back(pair<ll,ll>(x,y));
    }

    for(ll i = 0;i < v.size();i ++){

        x = v[i].first;
        y = v[i].second;
        ll j;
        ll last = -1;
        for(j = 0;j < v.size();j ++){
            if(i == j)
                continue;
            ll xx = v[j].first;
            ll yy = v[j].second;

            ll t = (x - xx)*(x - xx) + (y - yy)*(y - yy);
            if(last == -1){
                last = t;
                continue;
            }

            if(last != t)
                break;
        }
        if(j == v.size()){
            cout << i+1 << endl;
            return 0;
        }
    }
    cout << -1 <<endl;
    return 0;
}

B题

可以证明:最优情况下一定是最多只能有一行只选一部分,剩下n-1行要不整行全选,要不不选

假设第1行选择了前x个数字, 第2行选择了前y个数字,且x, y<m(都没选满一行)

那么可以知道a[2][y]>a[1][x+1],这样的话如果第二行选择前y-1个数字,第一行选择前x+1个一定更优

具体做法就是把所有行按从大到小排序,

然后求一个前缀和,顺便将每行的总和求出来,和行标放到一起做个排序

之后就是暴力匹配 找出k%m个数字  再将 k/m个的总和相加求最小值即可

具体做法看代码

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll N = 1e3 + 5;
const ll INF = 0x3f3f3f3f;
const ll mod = 1e9 + 7;
int a[N][N];
ll sum[N][N];
int n, m, k;
vector<pair<int,ll> > v;
bool cmp(pair<int,ll> a,pair<int,ll> b){
    return a.second < b.second;
}
int main()
{
    cin >> n >> m >> k;

    for(int i = 1;i <= n;i ++){

        for(int j = 1;j <= m;j ++){

            cin >> a[i][j];
        }

        sort(a[i] + 1,a[i] + 1 + m, greater<int>());
    }

    ll ans = 0;

    for(int i = 1;i <= n;i ++){

        for(int j = 1;j <= m;j ++)
            sum[i][j] = sum[i][j-1] + a[i][j];

        ans += sum[i][m];
        v.push_back(pair<int,ll>(i,sum[i][m]));
    }

    sort(v.begin(),v.end(),cmp);

    for(int i = 1;i <= n;i ++){

        int cnt = 0;
        ll t = sum[i][k%m];

        for(int j = 0;j < v.size();j ++){

            if(cnt == k / m)
                break;
            if(v[j].first == i && k % m)
                continue;

            t += v[j].second;
            cnt ++;
        }

        ans = min(ans,t);
    }
    cout << ans << endl;
    return 0;
}

 

阅读更多
换一批

没有更多推荐了,返回首页