Codeforces Round #256, 257 (Div. 2)

来源:互联网 发布:win8办公软件 编辑:程序博客网 时间:2024/06/14 03:00

CF(256) D. Multiplication Table

题目链接:http://codeforces.com/problemset/problem/448/D

思路:二分,不断逼近所想求的那个值


#include <iostream>#include <stdio.h>#include <string.h>#include <math.h>#include <queue>#include <vector>#include <queue>#include <iostream>#include <algorithm>#include <utility>#include <functional>using namespace std;long long n, m, k;int ok(long long num){    long long ans = 0;    for(int i = 1; i <= n; i++)    {        long long tt = min(m, num / i);        ans += tt;    }    if(ans < k)        return 0;    return 1;}int main(){    cin >> n >> m >> k;    long long l = 1, r = n * m;    while(l < r)    {        long long mid = (l + r) / 2;        if(ok(mid))            r = mid;        else            l = mid + 1;    }    cout << l << endl;}


CF 257 (DIV 2) :


A. 直接模拟即可

B.推出公式,注意如果所求值为负,那么需要注意有 while( f(n) < 0 ) 这样一个循环节


C.个n*m的方块的矩形上切k刀,最小的那一块最大可以是多少。如果纵向切k1刀,横向切k2刀,那么答案应该是 (n/(k1+1)) * (m/(k2+1)),且(K1+K2)为定值故由数学不等式知识知当k1与k2尽量差值大时,所求值越大


#include <iostream>#include <cstdio>#include <cstring>#include <algorithm>using namespace std;typedef long long int LL;LL n, m, k, ans = 0;int main(){    cin >> n >> m >> k;    if(n + m - 2 < k)    {        puts("-1");        return 0;    }    if(n + m - 2 == k)    {        puts("1");        return 0;    }    LL t;    if(m >= k + 1)        ans = max(ans, n * (m / (k + 1)));    else    {        t = k - m + 1;        ans = max(ans, n / (t + 1));    }    if(n >= k + 1)        ans = max(ans, m * (n / (k + 1)));    else    {        t = k - n + 1;        ans = max(ans, m / (t + 1));    }    cout << ans << endl;    return 0;}


D.给你n个城市,m条无向有权边。另外还有k条边,每条边从起到到i。求可以删除这k条边中的多少条,使得每个点到1的最短距离不变。

思路:对于每一个点,需要知道有无特殊边,如果有,则需判断能否通过无向边获得相同或更小距离,如果对于某点,存在2条以上最短路,即可删除到该点的特殊边,注意对于某点特殊边和无向边可能都不止一条,初次使用SPFA+SLF优化,真是道好题!



#include <stdio.h>#include <string.h>#include <string>#include <queue>#include <stack>#include <set>#include <math.h>#include <iostream>#include <algorithm>using namespace std;const int maxn = 1e6;const int inf = 0x3f3f3f3f;typedef long long ll;int n, m, k, cnt = 0;struct node{    int u;    int v;    int w;    int next;} edge[maxn];int ans, head[maxn], dis[maxn], vis[maxn];int cou[maxn], b[maxn];void add(int u, int v, int w){    edge[cnt].v = v;    edge[cnt].w = w;    edge[cnt].next = head[u];    head[u] = cnt++;}void spfa(){    int i, s = 1;    for(int i = 1; i <= n; i++)        dis[i] = inf;    deque <int> q;    q.push_back(s);    vis[s] = 1;    cou[s] = 1;    dis[s] = 0;    while(!q.empty())    {        int u = q.front();        q.pop_front();        vis[u] = 0;        for(i = head[u]; i != -1; i = edge[i].next)        {            if(dis[edge[i].v] > dis[u] + edge[i].w)            {                dis[edge[i].v] = dis[u] + edge[i].w;                cou[edge[i].v] = cou[u];                if(!vis[edge[i].v])                {                    vis[edge[i].v] = 1;                    if(!q.empty() && dis[edge[i].v] <= dis[q.front()])                    {                        q.push_front(edge[i].v);                    }                    else                        q.push_back(edge[i].v);                }            }            else                if(dis[edge[i].v] == dis[u] + edge[i].w)                {                    cou[edge[i].v] += cou[u];                    if(cou[edge[i].v] > 2)                        cou[edge[i].v] = 2;                }        }    }}int main(){    int u, v, w;    int sum = 0;    memset(vis, 0, sizeof(vis));    memset(head, -1, sizeof(head));    memset(b, inf, sizeof(b));    memset(cou, 0, sizeof(cou));    scanf("%d%d%d", &n, &m, &k);    for(int i = 0; i < m; i++)    {        scanf("%d%d%d", &u, &v, &w);        add(u, v, w);        add(v, u, w);    }    for(int i = 0; i < k; i++)    {        int v, w;        scanf("%d%d", &v, &w);        if(b[v] > w)            b[v] = w;    }    for(int i = 1; i <= n; i++)    {        if(b[i] != inf)        {            add(1, i, b[i]);            add(i, 1, b[i]);            sum++;        }    }    spfa();    for(int i = 1; i <= n; i++)    {        if(b[i] != inf)        {            if((dis[i] < b[i]) || (dis[i] == b[i] && cou[i] >= 2))                sum--;        }    }    printf("%d\n", k - sum);    return 0;}


0 0