hdu_3979, hdu_4310, hdu_4311, hdu_4313, hdu_4318

今天多校不知道怎么说了

被坑不说,还这么弱。。。大家都过的题,我们没有过

后来还是一直补总算理解的还行

3979跟今天多校第一题,即4310一样

贪心就行

不知道DP怎么搞。。

View Code
#include<cstdio>
#include<cstring>
#include<algorithm>

using namespace std;

struct node{
    int hp, g;
    double a;
    friend bool operator < (const node &a, const node &b){
        return a.a > b.a;
    }
}p[10000 + 10];
int main(){
    int tcase, z = 1;
    scanf("%d", &tcase);
    while(tcase --){
        int n, m;
        scanf("%d%d", &n, &m);
        for(int i = 0; i < n; i ++){
            scanf("%d%d", &p[i].hp, &p[i].g);
            p[i].a = 1.0 * p[i].g / ((p[i].hp - 1) /m +1);
        }
        sort(p, p + n);
        __int64 sum = 0;
        int t = 0;
        for(int i = 0; i < n; i ++){
            t += (p[i].hp - 1) / m + 1;
            sum += t * p[i].g;
            //t++;
        }
        printf("Case #%d: %I64d\n", z++, sum);
    }
    return 0;
}

4310就不多说了,暴力贪心的= =弱爆了

View Code
#include<cstdio>
#include<algorithm>
using namespace std;

struct node{
    int dps, hp;
    double sum;
    friend bool operator <(const node &a, const node &b)
    {
        return a.sum > b.sum;
    }
}p[30];

int main()
{
    int n;
    while(~scanf("%d", &n))
    {
        for(int i = 0; i < n;i ++)
        scanf("%d%d", &p[i].dps, &p[i].hp), p[i].sum = ((double)p[i].dps) / p[i].hp;
        int ans = 0;
        int flag = 0;
        sort(p, p + n);
        for(int i = 0; i < n;i ++)
        {
            int tmp = 0;
            for(int j = i; j < n; j ++)
            {
                tmp += p[j].dps;
            }
            ans += (tmp * p[i].hp);
            //printf("--%d\n", ans);
        }
        printf("%d\n", ans);
    }
    return 0;
}

4311最坑人了

一直把inf搞小了然后一直WA

这题数据弱

找中间值然后求附近100个点或者中位数之后暴力100个点都可以过,估计好多人是这样过的,只不过我们把inf取小了

标程的解法是我代码里的第一种

下面就引用吧

平面上两点间的 Manhattan 距离为 |x1-x2| + |y1-y2|

X 方向的距离与 Y 方向上的距离可以分开来处理。假设我们以 (xi,yi) 作为开会的地点,那么其余的点到该开会地点所需的时间为 X 方向上到 xi 所需要的时间加上 Y 方向上到 yi 所需要的时间。

对数据预处理后可以快速地求出x坐标小于xi的点的个数rankx, 并且这些 x 坐标值之和 sumx,那么这些点 X 方向上对结果的贡献为 rankx * xi - sumx;同理可以处理出 x 坐标大于 xi 的点在 X 方向上对结果的贡献值。同理可求得其余点在 Y 方向上到达 yi 所需要的总时间。

View Code
#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>

using namespace std;

const int maxn = 100000 + 10;

struct point{
    __int64 x, y, sumx, sumy;
    __int64 sum;
    __int64 sumxx, sumyy;
}p[maxn];
bool cmpx(point a, point b){
    return a.x < b.x;
}
bool cmpy(point a, point b){
    return a.y < b.y;
}
int main(){
    int tcase;
    scanf("%d", &tcase);
    while(tcase --){
        int n;
        scanf("%d", &n);
        for(int i = 1; i <= n; i ++){
            scanf("%I64d%I64d", &p[i].x, &p[i].y);
            p[i].sumxx = p[i].sumyy = 0;
        }
        sort(p + 1, p + n + 1, cmpx);
        for(int i = 1; i <= n; i ++){
            if(i == 1)
              p[i].sumx = p[i].x;
            else 
              p[i].sumx = p[i - 1].sumx + p[i].x;
        }
        for(int i = 1; i <= n; i ++){
            p[i].sumxx = i * p[i].x - p[i].sumx + p[n].sumx - p[i].sumx -(n - i ) * p[i].x;
        }
        sort(p + 1, p + n + 1, cmpy);
        for(int i = 1; i <= n; i ++){
        if(i == 1)
              p[i].sumy = p[i].y;
            else
              p[i].sumy = p[i - 1].sumy + p[i].y;
        }
        for(int i = 1; i <= n; i ++){
            p[i].sumyy = i * p[i].y - p[i].sumy + p[n].sumy - p[i].sumy - (n - i) * p[i].y;
        }
        __int64 ans = 1ll<<60;
        for(int i = 1; i <= n; i ++){
            __int64 tmp = p[i].sumyy + p[i].sumxx;
            //printf("tmp:  %d\n", tmp);
            if(tmp < ans)
              ans = tmp;
        }
        printf("%I64d\n", ans);
    }
    return 0;
}









/*
struct point{
    double x, y, dis;
//    friend bool operator < (const point &a, const point &b){
//        return a.dis < b.dis;
//    }
}p[maxn];
double distan(point a, point b){
    return fabs(a.x - b.x) + fabs(a.y - b.y);
}
__int64 allDis(int n, point f){
    __int64  sum = 0;
    for(int i = 0; i < n;i ++)
      sum += (__int64)distan(p[i], f);
    return sum;
}
bool cmp(point a, point b){
    return a.dis < b.dis;
}
bool cmp1(point a, point b){
    return a.x < b.x;
}
bool cmp2(point a, point b){
    return a.y < b.y;
}
int main(){
    int tcase;
    scanf("%d", &tcase);
    while(tcase --){
        int n;
        scanf("%d", &n);
        point anss;
        //anss.x = anss.y = 0.0;
        for(int i = 0; i < n;i ++){
            scanf("%lf%lf", &p[i].x, &p[i].y);
            //anss.x += p[i].x;
            //anss.y += p[i].y;
        }
        //anss.x /= n;
        //anss.y /= n;
        sort(p, p + n, cmp1);
        if(n & 1)
          anss.x = p[n / 2].x;
        else
          anss.x = (p[n/2].x + p[n/2-1].x)/2;
        sort(p, p + n, cmp2);
        if(n & 1)
          anss.y = p[n / 2].y;
        else
          anss.y = (p[n/2].y + p[n/2 -1].y)/2;
        for(int i = 0; i < n; i ++){
            p[i].dis = distan(anss, p[i]);
        }
        sort(p , p + n, cmp);
        double tmp = ~0U>>1;
        int max_ = min(100, n);
        __int64 minn = (1ll<<60);
        for(int i = 0; i < max_; i ++){
            __int64 temp = allDis(n, p[i]);

            if(minn > temp)
              minn = temp;
        }
        printf("%I64d\n", minn);
    }
    return 0;
}


struct point{
    double x, y, dis;
    friend bool operator < (const point &a, const point &b){
        return a.dis < b.dis;
    }
}p[maxn];
double distan(point a, point b){
    return fabs(a.x - b.x) + fabs(a.y - b.y);
}
double allDis(int n, point f){
    double sum = 0;
    for(int i = 0; i < n;i ++)
      sum += distan(p[i], f);
    return sum;
}
bool cmp(point a, point b){
    return a.dis < b.dis;
}
bool cmp1(point a, point b){
    return a.x < b.x;
}
bool cmp2(point a, point b){
    return a.y < b.y;
}
int main(){
    int tcase;
    scanf("%d", &tcase);
    while(tcase --){
        int n;
        scanf("%d", &n);
        point anss;
        //anss.x = anss.y = 0.0;
        for(int i = 0; i < n;i ++){
            scanf("%lf%lf", &p[i].x, &p[i].y);
            //anss.x += p[i].x;
            //anss.y += p[i].y;
        }
        //anss.x /= n;
        //anss.y /= n;
        sort(p, p + n, cmp1);
        if(n & 1)
          anss.x = p[n / 2].x;
        else
          anss.x = (p[n/2].x + p[n/2-1].x)/2;
        sort(p, p + n, cmp2);
        if(n & 1)
          anss.y = p[n / 2].y;
        else
          anss.y = (p[n/2].y + p[n/2 -1].y)/2;
        for(int i = 0; i < n; i ++){
            p[i].dis = distan(anss, p[i]);
        }
        sort(p , p + n, cmp);
        double tmp = (1ll<<60);
        int max_ = min(100, n);
        for(int i = 0; i < max_; i ++){
            double temp = allDis(n, p[i]);
            if(tmp > temp)
              tmp = temp;
        }
        printf("%.0f\n",tmp);
    }
    return 0;
}
*/

4313当时根本没想到是什么题

还是弱到爆啊

其实就是一个并查集

想到了没写。。也不敢写

估计一写又是一大堆BUG

其实就是看要不要加入那条边

View Code
#include<cstdio>
#include<cstring>
#include<algorithm>

using namespace std;
const int maxn = 100000 + 10;
int pre[maxn];
struct node{
    int u, v, w;
    friend bool operator < (const node &a, const node &b){
        return a.w > b.w;
    }
}p[maxn];
int find(int x){
    int s;
    for(s = x; s != pre[s]; s = pre[s]);
    while(s != x){
        int t = pre[x];
        pre[x] = s;
        x = t;
    }
    return s;
}

int vis[maxn];

int main(){
    int tcase;
    scanf("%d", &tcase);
    while(tcase --){
        int n, k;
        scanf("%d%d", &n, &k);
        memset(pre, -1, sizeof(pre));
        int u, v, w;
        for(int i = 0; i < n - 1; i ++){
            scanf("%d%d%d", &u, &v, &w);
            p[i].u = u;
            p[i].v = v;
            p[i].w = w;
            pre[i] = i;
        }
        pre[n - 1] = n - 1;
        sort(p, p + n - 1);
        memset(vis, 0, sizeof(vis));
        for(int i = 0; i < k; i ++)    {
            scanf("%d", &u);
            vis[u] = 1;
        }     
        __int64 sum = 0;
        int flag = 0;
        for(int i = 0; i < n - 1; i ++){
            int u = find(p[i].u);
            int v = find(p[i].v);
            if(vis[u] && vis[v])
              sum +=(__int64)p[i].w;
            else if(vis[u])
              pre[v] = u;
            else if(vis[v])
              pre[u] = v;
            else if(u < v)
              pre[v] = u;
            else
              pre[u] = v;
        }
        printf("%I64d\n", sum);
    }
    return 0;
}

4318边改边过的,都不知道怎么回事就过了

其实就是个简单的BFS了

不过也可以用最短路

我觉得难写还是用了BFS了

View Code
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
using namespace std;

const double inf=0.0-(~0U>>1);
const int maxn = 50000 + 10;
struct edge
{
    int to,w;
    edge*next;
}*list[maxn];
void add_edge(int u,int v,int w)
{
    edge *tmp=new edge;
    tmp->to=v;
    tmp->w=w;
    tmp->next=list[u];
    list[u]=tmp;
}
struct point
{
    int id;
    int sum;
};
double p[maxn];
int vis[maxn];
void bfs(int start,int v)
{
    queue<int>q;
    q.push(start);
    while(!q.empty())
    {
        int hd = q.front();
        q.pop();
        double sum = p[hd];
        edge *tmp = list[hd];
        while(tmp != NULL)
        {
            /*
            if(vis[tmp->to] == 1)
            {
                tmp = tmp->next;
                continue;
            }*/
            double cost = sum * (100.0 - tmp->w) / 100;
            if(cost > p[tmp->to])
            {
                q.push(tmp->to);
                p[tmp->to] = cost;
            }
            tmp = tmp->next;

            /*
            p[tmp->to] = max(cost, p[tmp->to]);
            if(tmp->to != v)
            {
                q.push(tmp->to);
                vis[tmp->to] = 1;
            }
            tmp = tmp->next;
            //puts("asdf");
            */
        }
    }
}

int main()
{
    int N;
    while(~scanf("%d", &N))
    {
        memset(list, NULL, sizeof(list));
        for(int i = 1; i <= N; i ++)
        {
            int k;
            scanf("%d", &k);
            while(k--)
            {
                int to, w;
                scanf("%d%d", &to, &w);
                add_edge(i, to, w);
            }
            p[i] = inf;
        }
        int u, v, sum;
        scanf("%d%d%d", &u, &v, &sum);
        //point start;
        //start.id = u;
        //start.sum = sum;
        //bfs(start);
        p[u] = sum;
        memset(vis, 0, sizeof(vis));
        vis[u] = 1;
        bfs(u,v);
        if(p[v] == inf)
            puts("IMPOSSIBLE!");
        else
            printf("%.2f\n", sum - p[v]);
    }
    return 0;
}

唉。。。。等下看两集海贼王就去睡觉吧

今天也搞的累了

有时间把多校热身赛的线段树给搞了

不能再拖了

妹子,晚安

原文地址:https://www.cnblogs.com/louzhang/p/2611059.html